C#高级编程技术复习一

基本的Socket编程进入

(注意:这是转的一篇2011年的文章,有些知识可能该更新了!)

这一篇文章,我将图文并茂地介绍Socket编程的基础知识,我相信,如果你按照步骤做完实验,一定可以对Socket编程有更好地理解。

本文源代码,可以通过这里下载 http://files.cnblogs.com/chenxizhang/SocketWorkshop.rar

第一步:创建解决方案

第二步:创建服务端程序

这里可以选择“Console Application”这个类型,比较方便调试

然后编写如下代码,实现服务器的基本功能

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

//额外导入的两个命名空间
using System.Net.Sockets;
using System.Net;

namespace SocketServer
{
    class Program
    {
        /// <summary>
        /// Socket Server 演示
        /// 作者:陈希章
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            //创建一个新的Socket,这里我们使用最常用的基于TCP的Stream Socket(流式套接字)
            var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            //将该socket绑定到主机上面的某个端口
            //方法参考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.bind.aspx
            socket.Bind(new IPEndPoint(IPAddress.Any, 4530));

            //启动监听,并且设置一个最大的队列长度
            //方法参考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.listen(v=VS.100).aspx
            socket.Listen(4);

            Console.WriteLine("Server is ready!");
            Console.Read();
        }
    }
}

现在可以启动调试一下看看效果如何,正常情况下应该会看到一个提示,因为我们需要在TCP 4530端口进行监听,所以防火墙会有提示。

点击“Allow access”

这样,我们的服务器就可以开始监听了。但是这有什么用呢?是的,没有什么用。

我们还需要为服务器添加一些功能,例如接受传入的请求,给客户端发送消息,或者从客户端接收消息等等

第三步:接受传入的请求

我们需要通过Accept,或者(BeginAccept)来接受传入的请求,请注意下面代码中的红色部分

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

//额外导入的两个命名空间
using System.Net.Sockets;
using System.Net;

namespace SocketServer
{
    class Program
    {
        /// <summary>
        /// Socket Server 演示
        /// 作者:陈希章
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            //创建一个新的Socket,这里我们使用最常用的基于TCP的Stream Socket(流式套接字)
            var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            //将该socket绑定到主机上面的某个端口
            //方法参考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.bind.aspx
            socket.Bind(new IPEndPoint(IPAddress.Any, 4530));

            //启动监听,并且设置一个最大的队列长度
            //方法参考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.listen(v=VS.100).aspx
            socket.Listen(4);

            //开始接受客户端连接请求
            //方法参考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.beginaccept.aspx
            socket.BeginAccept(new AsyncCallback((ar) =>
            {
                //这就是客户端的Socket实例,我们后续可以将其保存起来
                var client = socket.EndAccept(ar);

                //给客户端发送一个欢迎消息
                client.Send(Encoding.Unicode.GetBytes("Hi there, I accept you request at "+DateTime.Now.ToString()));
            }), null);

            Console.WriteLine("Server is ready!");
            Console.Read();
        }
    }
}

wow,看起来不错对吧,我们赶紧做一个客户端来测试一下吧

第四步:创建客户端

我们还是使用一个Console Application

添加如下的代码,并且创建客户端连接

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

//导入的命名空间
using System.Net.Sockets;

namespace SocketClient
{
    class Program
    {
        /// <summary>
        /// Socket Server 演示
        /// 作者:陈希章
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            //创建一个Socket
            var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            //连接到指定服务器的指定端口
            //方法参考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.connect.aspx
            socket.Connect("localhost", 4530);

            Console.WriteLine("connect to the server");
            Console.Read();

        }
    }
}

依次选择SocketServer和SocketClient这两个项目,分别将其启动为调试状态(右键菜单,Debug=>Start new instance)

我们看到两个程序都工作正常。

但是,在客户端怎么没有收到服务器发过来的消息呢?那是因为,我们没有在客户端提供这方面的功能。

第五步:在客户端中实现接受消息的方法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

//导入的命名空间
using System.Net.Sockets;

namespace SocketClient
{
    class Program
    {
        /// <summary>
        /// Socket Server 演示
        /// 作者:陈希章
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            //创建一个Socket
            var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            //连接到指定服务器的指定端口
            //方法参考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.connect.aspx
            socket.Connect("localhost", 4530);

            //实现接受消息的方法

            var buffer = new byte[1024];//设置一个缓冲区,用来保存数据
            //方法参考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.beginreceive.aspx
            socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback((ar) =>
            {
                //方法参考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.endreceive.aspx
                var length = socket.EndReceive(ar);
                //读取出来消息内容
                var message = Encoding.Unicode.GetString(buffer, 0, length);
                //显示消息
                Console.WriteLine(message);

            }), null);

            Console.WriteLine("connect to the server");
            Console.Read();

        }
    }
}

请注意以上红色的部分,我们用了BeginReceive方法进行异步的消息侦听,如果收到了,我们就打印出来

看起来已经实现了我们需求了:服务器给客户端发了一个消息,而客户端也已经收到了。

但是,这远远不够,因为它们之间的通讯不仅仅是一次性的,那么如果服务器要不断地给客户端发消息,例如每隔两秒钟就发送一个消息,如何实现呢?

第六步:实现服务器定期向客户端发消息

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

//额外导入的两个命名空间
using System.Net.Sockets;
using System.Net;

namespace SocketServer
{
    class Program
    {
        /// <summary>
        /// Socket Server 演示
        /// 作者:陈希章
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            //创建一个新的Socket,这里我们使用最常用的基于TCP的Stream Socket(流式套接字)
            var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            //将该socket绑定到主机上面的某个端口
            //方法参考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.bind.aspx
            socket.Bind(new IPEndPoint(IPAddress.Any, 4530));

            //启动监听,并且设置一个最大的队列长度
            //方法参考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.listen(v=VS.100).aspx
            socket.Listen(4);

            //开始接受客户端连接请求
            //方法参考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.beginaccept.aspx
            socket.BeginAccept(new AsyncCallback((ar) =>
            {
                //这就是客户端的Socket实例,我们后续可以将其保存起来
                var client = socket.EndAccept(ar);

                //给客户端发送一个欢迎消息
                client.Send(Encoding.Unicode.GetBytes("Hi there, I accept you request at "+DateTime.Now.ToString()));

                //实现每隔两秒钟给服务器发一个消息
                //这里我们使用了一个定时器
                var timer = new System.Timers.Timer();
                timer.Interval = 2000D;
                timer.Enabled = true;
                timer.Elapsed += (o, a) =>
                {
                    client.Send(Encoding.Unicode.GetBytes("Message from server at " +DateTime.Now.ToString()));
                };
                timer.Start();

            }), null);

            Console.WriteLine("Server is ready!");
            Console.Read();
        }
    }
}

我们还要实现在客户端一直监听消息的机制,而不是一次性接收.请注意下面红色的部分

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

//导入的命名空间
using System.Net.Sockets;

namespace SocketClient
{
    class Program
    {
        /// <summary>
        /// Socket Server 演示
        /// 作者:陈希章
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            //创建一个Socket
            var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            //连接到指定服务器的指定端口
            //方法参考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.connect.aspx
            socket.Connect("localhost", 4530);
            Console.WriteLine("connect to the server");

            //实现接受消息的方法

            //方法参考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.beginreceive.aspx
            socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveMessage),socket);

            Console.Read();

        }

        static byte[] buffer = new byte[1024];

        public static void ReceiveMessage(IAsyncResult ar)
        {
            try
            {
                var socket = ar.AsyncState as Socket;

                //方法参考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.endreceive.aspx
                var length = socket.EndReceive(ar);
                //读取出来消息内容
                var message = Encoding.Unicode.GetString(buffer, 0, length);
                //显示消息
                Console.WriteLine(message);

                //接收下一个消息(因为这是一个递归的调用,所以这样就可以一直接收消息了)
                socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), socket);
            }
            catch(Exception ex){
                Console.WriteLine(ex.Message);
            }
        }
    }
}

重新调试起来,看起来的效果如下图所示

我们继续做下面的实验,一步一步地研究Socket通讯中可能遇到的一些问题

请先关闭掉客户端这个程序,而不要关闭服务端程序,这时会发现一个错误

这个错误很容易理解,因为客户端已经关闭,也就是客户端那个Socket已经不存在了,服务器还继续向它发送消息当然会出错。所以,从可靠性方面的考虑,我们必须在发送消息之前检测Socket的活动状态

第七步:检测客户端的活动状态

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

//额外导入的两个命名空间
using System.Net.Sockets;
using System.Net;

namespace SocketServer
{
    class Program
    {
        /// <summary>
        /// Socket Server 演示
        /// 作者:陈希章
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            //创建一个新的Socket,这里我们使用最常用的基于TCP的Stream Socket(流式套接字)
            var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            //将该socket绑定到主机上面的某个端口
            //方法参考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.bind.aspx
            socket.Bind(new IPEndPoint(IPAddress.Any, 4530));

            //启动监听,并且设置一个最大的队列长度
            //方法参考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.listen(v=VS.100).aspx
            socket.Listen(4);

            //开始接受客户端连接请求
            //方法参考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.beginaccept.aspx
            socket.BeginAccept(new AsyncCallback((ar) =>
            {
                //这就是客户端的Socket实例,我们后续可以将其保存起来
                var client = socket.EndAccept(ar);

                //给客户端发送一个欢迎消息
                client.Send(Encoding.Unicode.GetBytes("Hi there, I accept you request at "+DateTime.Now.ToString()));

                //实现每隔两秒钟给服务器发一个消息
                //这里我们使用了一个定时器
                var timer = new System.Timers.Timer();
                timer.Interval = 2000D;
                timer.Enabled = true;
                timer.Elapsed += (o, a) =>
                {
                    //检测客户端Socket的状态
                    if(client.Connected)
                    {
                        try
                        {
                            client.Send(Encoding.Unicode.GetBytes("Message from server at " + DateTime.Now.ToString()));
                        }
                        catch(SocketException ex)
                        {
                            Console.WriteLine(ex.Message);
                        }
                    }
                    else
                    {
                        timer.Stop();
                        timer.Enabled = false;
                        Console.WriteLine("Client is disconnected, the timer is stop.");
                    }
                };
                timer.Start();

            }), null);

            Console.WriteLine("Server is ready!");
            Console.Read();
        }
    }
}

上面代码的逻辑很清楚,但有时候还是会触发那个SocketException。为什么呢?这是因为我们的Timer是每隔两秒钟检查一次,那么就很可能有一种情况,我们检查的时候,它还是连接状态,消息发出去之后,它断开了。这种情况肯定是存在的。所以要用Try..catch的结构

目前我们实现的场景很简单,服务器只管发消息,客户端只管收消息。但实际工作中,可能希望服务器和客户端都能收发消息。请看下一节

第八步:实现双向收发消息

先看服务端的修改

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

//额外导入的两个命名空间
using System.Net.Sockets;
using System.Net;

namespace SocketServer
{
    class Program
    {
        /// <summary>
        /// Socket Server 演示
        /// 作者:陈希章
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            //创建一个新的Socket,这里我们使用最常用的基于TCP的Stream Socket(流式套接字)
            var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            //将该socket绑定到主机上面的某个端口
            //方法参考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.bind.aspx
            socket.Bind(new IPEndPoint(IPAddress.Any, 4530));

            //启动监听,并且设置一个最大的队列长度
            //方法参考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.listen(v=VS.100).aspx
            socket.Listen(4);

            //开始接受客户端连接请求
            //方法参考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.beginaccept.aspx
            socket.BeginAccept(new AsyncCallback((ar) =>
            {
                //这就是客户端的Socket实例,我们后续可以将其保存起来
                var client = socket.EndAccept(ar);

                //给客户端发送一个欢迎消息
                client.Send(Encoding.Unicode.GetBytes("Hi there, I accept you request at "+DateTime.Now.ToString()));

                //实现每隔两秒钟给服务器发一个消息
                //这里我们使用了一个定时器
                var timer = new System.Timers.Timer();
                timer.Interval = 2000D;
                timer.Enabled = true;
                timer.Elapsed += (o, a) =>
                {
                    //检测客户端Socket的状态
                    if(client.Connected)
                    {
                        try
                        {
                            client.Send(Encoding.Unicode.GetBytes("Message from server at " + DateTime.Now.ToString()));
                        }
                        catch(SocketException ex)
                        {
                            Console.WriteLine(ex.Message);
                        }
                    }
                    else
                    {
                        timer.Stop();
                        timer.Enabled = false;
                        Console.WriteLine("Client is disconnected, the timer is stop.");
                    }
                };
                timer.Start();

                //接收客户端的消息(这个和在客户端实现的方式是一样的)
                client.BeginReceive(buffer,0,buffer.Length,SocketFlags.None,new AsyncCallback(ReceiveMessage),client);

            }), null);

            Console.WriteLine("Server is ready!");
            Console.Read();
        }

        static byte[] buffer = new byte[1024];

        public static void ReceiveMessage(IAsyncResult ar)
        {
            try
            {
                var socket = ar.AsyncState as Socket;

                //方法参考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.endreceive.aspx
                var length = socket.EndReceive(ar);
                //读取出来消息内容
                var message = Encoding.Unicode.GetString(buffer, 0, length);
                //显示消息
                Console.WriteLine(message);

                //接收下一个消息(因为这是一个递归的调用,所以这样就可以一直接收消息了)
                socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), socket);
            }
            catch(Exception ex){
                Console.WriteLine(ex.Message);
            }
        }
    }
}

可以看出来,为了让服务器可以接受消息,其实并不需要什么特别的设计,与客户端接受消息其实可以是一样的

再来看看客户端的修改

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

//导入的命名空间
using System.Net.Sockets;

namespace SocketClient
{
    class Program
    {
        /// <summary>
        /// Socket Server 演示
        /// 作者:陈希章
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            //创建一个Socket
            var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            //连接到指定服务器的指定端口
            //方法参考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.connect.aspx
            socket.Connect("localhost", 4530);
            Console.WriteLine("connect to the server");

            //实现接受消息的方法

            //方法参考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.beginreceive.aspx
            socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), socket);

            //接受用户输入,将消息发送给服务器端
            while(true)
            {
                var message = "Message from client : " + Console.ReadLine();
                var outputBuffer = Encoding.Unicode.GetBytes(message);
                socket.BeginSend(outputBuffer, 0, outputBuffer.Length, SocketFlags.None, null, null);
            }

        }

        static byte[] buffer = new byte[1024];

        public static void ReceiveMessage(IAsyncResult ar)
        {
            try
            {
                var socket = ar.AsyncState as Socket;

                //方法参考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.endreceive.aspx
                var length = socket.EndReceive(ar);
                //读取出来消息内容
                var message = Encoding.Unicode.GetString(buffer, 0, length);
                //显示消息
                Console.WriteLine(message);

                //接收下一个消息(因为这是一个递归的调用,所以这样就可以一直接收消息了)
                socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), socket);
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
    }
}

我在这里做了一个死循环,用户可以不断地输入,这些消息会被发送给服务器。如下图所示

【备注】因为服务器每隔两秒钟会发送新消息过来,所以在输入的时候,动作要稍快一点啦

本文最后探讨一个问题,就是如何让我们的服务器可以支持多个客户端

第九步:支持多个客户端

这个步骤只需要修改服务端程序即可

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

//额外导入的两个命名空间
using System.Net.Sockets;
using System.Net;

namespace SocketServer
{
    class Program
    {
        /// <summary>
        /// Socket Server 演示
        /// 作者:陈希章
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            //创建一个新的Socket,这里我们使用最常用的基于TCP的Stream Socket(流式套接字)
            var socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            //将该socket绑定到主机上面的某个端口
            //方法参考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.bind.aspx
            socket.Bind(new IPEndPoint(IPAddress.Any, 4530));

            //启动监听,并且设置一个最大的队列长度
            //方法参考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.listen(v=VS.100).aspx
            socket.Listen(4);

            //开始接受客户端连接请求
            //方法参考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.beginaccept.aspx
            socket.BeginAccept(new AsyncCallback(ClientAccepted), socket);

            Console.WriteLine("Server is ready!");
            Console.Read();
        }

        public static void ClientAccepted(IAsyncResult ar)
        {

            var socket = ar.AsyncState as Socket;

            //这就是客户端的Socket实例,我们后续可以将其保存起来
            var client = socket.EndAccept(ar);

            //给客户端发送一个欢迎消息
            client.Send(Encoding.Unicode.GetBytes("Hi there, I accept you request at " + DateTime.Now.ToString()));

            //实现每隔两秒钟给服务器发一个消息
            //这里我们使用了一个定时器
            var timer = new System.Timers.Timer();
            timer.Interval = 2000D;
            timer.Enabled = true;
            timer.Elapsed += (o, a) =>
            {
                //检测客户端Socket的状态
                if(client.Connected)
                {
                    try
                    {
                        client.Send(Encoding.Unicode.GetBytes("Message from server at " + DateTime.Now.ToString()));
                    }
                    catch(SocketException ex)
                    {
                        Console.WriteLine(ex.Message);
                    }
                }
                else
                {
                    timer.Stop();
                    timer.Enabled = false;
                    Console.WriteLine("Client is disconnected, the timer is stop.");
                }
            };
            timer.Start();

            //接收客户端的消息(这个和在客户端实现的方式是一样的)
            client.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), client);

            //准备接受下一个客户端请求
            socket.BeginAccept(new AsyncCallback(ClientAccepted), socket);
        }

        static byte[] buffer = new byte[1024];

        public static void ReceiveMessage(IAsyncResult ar)
        {

            try
            {
                var socket = ar.AsyncState as Socket;

                //方法参考:http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.endreceive.aspx
                var length = socket.EndReceive(ar);
                //读取出来消息内容
                var message = Encoding.Unicode.GetString(buffer, 0, length);
                //显示消息
                Console.WriteLine(message);

                //接收下一个消息(因为这是一个递归的调用,所以这样就可以一直接收消息了)
                socket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveMessage), socket);
            }
            catch(Exception ex){
                Console.WriteLine(ex.Message);
            }
        }
    }
}

最后调试起来看到的效果如下图

本文源代码,可以通过这里下载 http://files.cnblogs.com/chenxizhang/SocketWorkshop.rar

时间: 2024-07-29 17:23:25

C#高级编程技术复习一的相关文章

《好学的C++ 第2版》 第9章 一些高级编程技术

转向C++0x和OOP之前,需要掌握其他一些技巧. C++命令行参数: main函数须这样定义: int main(int argc, char* argv[]){/*...*/}  //argc计数包括程序名,所以至少是1:argv[0]就是程序名.这两个参数可以任意使用,但是是只读的,可以随意显示或复制它们.程序中可以通过argc判断输入参数是否足够(例如大于1),通过argv判断各参数是否合法,合法的话存入其他变量使用:不合法的话提示输入后,存入其他变量中使用即可.MAX_PATH:系统能

第三部分 F# 高级编程技术

在第二部分,我们讨论了大多数函数语言常见的函数概念.现在可以说已经理解了函数式编程,就像在阅读了封装.继承和多态性以后,可以说熟悉面向对象编程一样:但要想成为有效的面向对象的开发人员,还需要学习其他内容,用 F# 进行函数编程也没有什么不同. 就像每种面向对象语言的功能各有特色一样,在 F# 中也有一些特有的功能,在其他函数语言中通常没有,当我们在第九章讨论有关对象的类型和成员时,会看到这方面的示例.在 .NET 世界中,F# 是一等公民(first-class citizen),能够使用和声明

[GeekBand]C++高级编程技术(2)

本篇笔记主要分为两个主要部分,第一部分关于对象模型,第二部分是关于new和delete的更加深入的学习. 对象模型 关于vptr(虚指针)和vtbl(虚函数表) 只要用到了虚函数,对象中就会多一个指向虚函数表的虚指针.在32位环境下,将占4Bytes的空间. 在vtbl中,每一项都是指向自己类应当调用的虚函数的函数指针. 2.静态绑定与动态绑定 在C中,对于不同的函数名采用静态绑定的方法,每个函数直接对应了一个地址,存储在相应的位置中.在C++中,非虚的成员函数也用静态绑定的方式被存储.如上图中

【高级编程技术作业】第三周

5-2 5-6 5-8 5-9 5-11 6-1 6-5 6-9 原文地址:https://www.cnblogs.com/dhlee/p/python.html

【高级编程技术作业】第四周

7-1 7-2 7-3 7-6 7-7 8-1 8-2 8-5 原文地址:https://www.cnblogs.com/dhlee/p/8723688.html

【高级编程技术作业】第六周

11-1 11-2 11-3 原文地址:https://www.cnblogs.com/dhlee/p/8805933.html

【高级编程技术作业】第五周

9-1 9-2 9-3 9-5 9-7 10-3 10-4 10-5 10-6 10-7 原文地址:https://www.cnblogs.com/dhlee/p/8830554.html

Android开发经典书籍下载——《Android 4高级编程》《疯狂Android讲义》《Android应用开发详解(郭宏志)》《Android应用案例开发大全》《Android 3D游戏开发技术》

这是我收集的关于android开发方面的经典书籍,高清PDF电子版,可以在我的百度网盘免费下载,希望对需要的朋友有帮助. 目录: <Android 4高级编程>(附完整源代码) <疯狂Android讲义> <Android应用开发详解(郭宏志)> <Android应用案例开发大全> <Android 3D游戏开发技术> <Android内核剖析 柯元旦> <深入理解Android  卷1> <深入理解Android

重学《C#高级编程》(序)

小生码农一枚,以前只是看别人写博客,从来没有想过要自己写博文,突然之间“脑抽”想自己也写点什么,遂在博客园开通这个博客. 简单介绍下自己吧,本人90后,父母对我没有大的想法,只是希望我平安成长,多学习以后不当农民就行(-_-什么想法嘛,现在的农民很值钱的),所以给取名叫“小升”,意为做事小升一步就行.不知道是不是名称的原因,导致现在在社会爬得很艰难,25.6了还是屌丝码农一枚. 题外话扯多了,步入正题吧,小升我没有什么高学历,初中毕业,经历过的最高等学府也只是北大青鸟的初级班,主流技术都是自己看