• WinForm TCP异步连接之服务器端


    TCP连接之服务器端,涉及到如下三个函数,分别是:

    复制代码
    /*****************************
      ** 函数功能:
         服务端监听
      ** 输入参数:    
      ** 输出参数:
     ******************************/
     private void ServerListen(){}
    复制代码
    复制代码
    /******************************
     ** 函数功能:
        用于与客户端取得连接
     ** 输入参数: 
     ** 输出参数:
     ******************************/
     private void AcceptConnect(){}
    复制代码
    复制代码
    /******************************
     ** 函数功能:
        接受客户端发回的信息
     ** 输入参数: 
         ar:客户端发回的信息
     ** 输出参数:
     ******************************/
     private void ReadCallback(IasyncResult ar){}
    复制代码

    三者的关系图如下:

    具体代码如下:

    1、ServerListen()

    private bool isExit = false;
     TcpListener listener;
      //用于线程同步,初始状态设为非终止状态,使用手动重置方式
     private EventWaitHandle allDone = new EventWaitHandle(false, EventResetMode.ManualReset);
    
      /******************************
       ** 作者: ***
       ** 变更时间: 2012-12-26
      ******************************/
      #region 服务端监听方法
      private void ServerListen()
      {
          //由于服务器要为多个客户服务,所以需要创建一个线程监听客户端连接请求
         ThreadStart ts = new ThreadStart(AcceptConnect);
          Thread myThread = new Thread(ts);
          myThread.Start();
      }
     #endregion
    

      

    2、AcceptConnect()

    /******************************
       ** 作者: ***
      ** 变更时间: 2012-12-26
     ******************************/
     #region 与客户机取得连接
     private void AcceptConnect()
     {
          //获取本机所有IP地址 
         IPAddress[] localips = Dns.GetHostAddresses(Dns.GetHostName());
        
          foreach (IPAddress ip in localips)
          {
              //找到本地所有IP地址符合IPV4协议的IP地址
            if (ip.AddressFamily == AddressFamily.InterNetwork)
              {
                    IPAddress ip4;
                    ip4 = ip;
                    listener = new TcpListener(ip4, 5000);
                    listener.Start();
                    break;
               }
           }
    
           //引用在异步操作完成时调用的回调方法
         AsyncCallback callback = new AsyncCallback(AcceptTcpClientCallback);
    
           while (isExit == false)
           {
               //将事件的状态设为非终止
             allDone.Reset();
    
               //开始一个异步操作接受传入的连接尝试
             listener.BeginAcceptTcpClient(callback, listener);
    
               //阻塞当前线程,直到收到客户连接信号
             allDone.WaitOne();
    
                Thread.Sleep(100);
            }
     }
     #endregion
    

      

    3、AcceptTcpClientCallback()

    /******************************
       ** 作者: ***
      ** 变更时间: 2012-12-26
     ******************************/
     #region 连接客户端的回调函数
     //ar是IAsyncResult类型的接口,表示异步操作的状态是由listener.BeginAcceptTcpClient(callback, listener)传递过来的
     
      private void AcceptTcpClientCallback(IAsyncResult ar)
      {
          //将事件状态设为终止状态,允许一个或多个等待线程继续
         allDone.Set();
          TcpListener myListener = (TcpListener)ar.AsyncState;
    
          //异步接收传入的连接,并创建新的TcpClient对象处理远程主机通信
         TcpClient client = myListener.EndAcceptTcpClient(ar);
          ReadWriteObject readWriteObject = new ReadWriteObject(client);
    
          readWriteObject.netStream.BeginRead(readWriteObject.readBytes, 0, readWriteObject.readBytes.Length, ReadCallback, readWriteObject);
       }
     #endregion
    

      

    4、ReadCallback()

    byte[] tem = new byte[24];
      byte[] Msgbody;
      byte[] ErrorEndTime;
      ByteToObject bytetoobject = new ByteToObject();
    
      /******************************
       ** 作者: ***
       ** 变更时间: 2012-12-02
      ******************************/
      #region 接收客户端发来的信息,ar为异步方法下客户端发回的信息
      private void ReadCallback(IAsyncResult ar)
      {
            ReadWriteObject readWriteObject = (ReadWriteObject)ar.AsyncState;
            int length = readWriteObject.netStream.EndRead(ar);
            tem = new byte[24];
            Array.Copy(readWriteObject.readBytes, 0, tem, 0, 24);
    
            //MsgHead为自定义的结构体
            MsgHead msghead = (MsgHead)bytetoobject.BytesToStuct(tem, typeof(MsgHead));
           if (length > 0 && msghead.Sync == 0x4D)
           {
               switch (msghead.MsgType)
               {
                    //根据收到的信息的头部来执行下面的操作
               }
           }          
      }
    

      

  • 相关阅读:
    R安装程序包:ERROR: failed to lock directory ‘/usr/lib64/R/library’ for modifying
    clusterProfiler
    R 画图保存为文件
    网站支持https之一:https原理和SSL证书类型
    Https系列之一:https的简单介绍及SSL证书的生成
    What is the difference between a directory and a folder?
    漫画解读:通过造车来了解软件开发模式 DevOps
    Multicast delegate of type Func (with return value)?
    What are good ways to prevent SQL injection? [duplicate]
    SqlCommand.Prepare Method
  • 原文地址:https://www.cnblogs.com/vic_lu/p/8976223.html
Copyright © 2020-2023  润新知