码迷,mamicode.com
首页 > 其他好文 > 详细

Socket异步通信学习二

时间:2016-07-19 09:23:17      阅读:144      评论:0      收藏:0      [点我收藏+]

标签:

接下来是服务器部分,采用异步模式,新建了一个AsynServer类,用于存放socket服务器代码,主要有4个方法:

有一个全局socket,下面四个方法中都用到。

Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

类框架如下:

技术分享

1.构造方法public AsynServer(IPEndPoint endpoint,int listenMaxNum)

  用于初始化socket服务器,IPEndPoint参数是socket绑定的终结点,listenMaxNum参数是监听队列的挂起的最大长度,代码如下:

  public AsynServer(IPEndPoint endpoint,int listenMaxNum)
        {       
                socket.Bind(endpoint);      //绑定终结点
                socket.Listen(listenMaxNum);//将socket至于侦听状态,设置挂起队列最大值为listenMaxNum
                Console.WriteLine("正在连接客户端....");
                AsynAccept();         //开始异步监听
       //     return socket;
        }

2.异步监听方法public void AsynAccept()

技术分享
public void AsynAccept()
        {
                socket.BeginAccept(asyncResult => {
                socket = socket.EndAccept(asyncResult);         //异步监听成功,返回socket
                Console.WriteLine("客户端{0}异步连接成功", socket.RemoteEndPoint.ToString());            
                AsynReceive();
                    AsynSend("Server:Hello,client!");
            }, null);
        }
View Code

需注意的是异步socket的BeginAccept()方法必须以EndAccept()方法结束,EndAccept(asyncResult)通过回调BeginAccept中的asyncResult状态信息返回socket,这个socket是与客户端建立连接后的socket,需要把它赋给全局socket(后面的方法中会调用)。

另外,AsynAccept并不会阻塞主线程,因为系统会为BeginAccept()方法自动开一个线程,并阻塞该线程直到收到客户端连接,回调lamda表达式中的接收代码。

采用lamda变得式写的回调函数,不熟悉的同学请恶补一下吧,用起来很方便的:-)

连接成功了会收到客户端发来的信息,(AsynReceive()也是异步的,不会阻碍主线程),并给客户端发送问候信息,(AsynReceive()和AsynSend()都是异步的,不会阻碍主线程)。

3.异步接收方法private  void AsynReceive()

技术分享
  private  void AsynReceive()
        {
            byte[] data = new byte[1024];//接收缓存
            string receiveStr;
            socket.BeginReceive(data, 0, data.Length, SocketFlags.None, asyncResult => {
                int length = socket.EndReceive(asyncResult);
                if (length != 0)
                {
                    receiveStr = Encoding.ASCII.GetString(data, 0, length);//获取缓存中的信息
                    Console.WriteLine(receiveStr);
                      
                    AsynReceive();//继续开新线程接收
                }
                else {
                        
                    Console.WriteLine("客户端{0}:关闭socket连接", socket.RemoteEndPoint.ToString());//socket.RemoteEndPoint.ToString()是客户端IP地址
                    socket.Close();
                }
            }, null);
            
            
        }
AsynReceive()

4.异步发送方法public void AsynSend()

技术分享
 public void AsynSend(string msg)
        {
            byte[] data = Encoding.UTF8.GetBytes(msg);
            socket.BeginSend(data, 0, data.Length, SocketFlags.None, asyncResult =>
            {
                int length = socket.EndSend(asyncResult);
                Console.WriteLine("message send to {0} successfully", socket.RemoteEndPoint.ToString());
            }, null);            
        }
public void AsynSend(string msg)

因为socket收发都是采用字节流的形式,所以接收需要用byte[] data = new byte[1024],缓存收到的字节流,然后通过Encoding.ASCII.GetString(data, 0, length)方法把字节流转化为字符串输出;发送通过byte[] data = Encoding.UTF8.GetBytes(msg),把字符串信息转化为字节流发送。EndReceive(),EndSend()方法返回的都是收发字节数(int)

以上都是最简单的,只能实现基本的通信功能,后期会在此基础上完善,帮助初学者少走弯路,我当时可是学的头昏眼花-_-||

下篇是采用与服务器完全不同模式的客户端,同步模式

Socket异步通信学习二

标签:

原文地址:http://www.cnblogs.com/gongheng/p/5683241.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!