C# TCP通讯

服务端代码

C# — 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)
           {
                //根据收到的信息的头部来执行下面的操作
           }
       }          
  }

  

客户端代码

C# — WinForm TCP连接之客户端
TCP连接之客户端,涉及到如下三个函数,分别是:


/*****************************
  ** 函数功能:
     用于与服务端进行TCP连接
  ** 输入参数: 
      IP:IP地址
        Port:端口号        
  ** 输出参数:
 ******************************/
 private void ClientConnect(string IP, string Port){}

 


/******************************
 ** 函数功能:
    用于向服务端发送信息
 ** 输入参数: 
     MsgType:TCP协议中的协议头部
 ** 输出参数:
 ******************************/
 private void ClientSendMsg(ushort MsgType){}

 


/******************************
  ** 函数功能:
     接受服务端发回的信息
  ** 输入参数: 
  ** 输出参数:
 ******************************/
  private void RecMsg(){}

三者的关系图如下:
 

具体代码如下:

1、ClientConnect()



/******************************
  ** 作者: ***
 ** 变更时间: 2012-12-02
 ******************************/
 #region 连接服务端方法
 private void ClientConnect(string IP, string Port)
 {
     //定义一个套字节监听  包含3个参数(IP4寻址协议,流式连接,TCP协议)
     socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

     //需要获取文本框中的IP地址
    IPAddress ipaddress = IPAddress.Parse(IP);
     //将获取的ip地址和端口号绑定到网络节点endpoint上
   IPEndPoint endpoint = new IPEndPoint(ipaddress, int.Parse(Port));

     //这里客户端套接字连接到网络节点(服务端)用的方法是Connect 而不是Bind
     socketClient.Connect(endpoint);

     //创建一个线程 用于监听服务端发来的消息
    threadClient = new Thread(RecMsg);

     //将窗体线程设置为与后台同步
    threadClient.IsBackground = true;

     //启动线程
    threadClient.Start();
 }
 #endregion

 

2、ClientSendMsg()



/******************************
  ** 作者: ***
 ** 变更时间: 2012-12-02
 ******************************/
 #region 发送节目全屏byte串信息到服务端的方法
 private void ClientSendMsg(ushort MsgType)
 {
      //调用客户端套接字发送字节数组
     socketClient.Send(addHeadBody);
 }
 #endregion


3、RecMsg()



/******************************
  ** 作者: 郭乐彬
  ** 变更时间: 2012-11-30
 ******************************/
 #region 接收服务端发来信息的方法
 private void RecMsg()
 {
     while (true) //持续监听服务端发来的消息
    {
         //定义一个1024*200的内存缓冲区 用于临时性存储接收到的信息
       byte[] arrRecMsg = new byte[1024 * 200];

         //将客户端套接字接收到的数据存入内存缓冲区, 并获取其长度
       int length = socketClient.Receive(arrRecMsg);

        byte[] tem = new byte[24];
        Array.Copy(arrRecMsg, 0, tem, 0, 24);

        ByteToObject bytetoobject = new ByteToObject();
        //MsgHead为一个自定义的结构体
        MsgHead msghead = (MsgHead)bytetoobject.BytesToStuct(tem, typeof(MsgHead));
  
        switch (msghead.MsgType)
        {
              //根据自定义的TCP协议中规定的头部来决定后面的操作
       }
     }
}

  

原文地址:https://www.cnblogs.com/baylor2019/p/13629504.html