基于Socket实现TCP/IP通讯

一、TCP/IP服务器

1、开启服务

//初始化用于监听的Socket套接字
            serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            //获取本地IP
            IPAddress ip = IPAddress.Parse(this.txt_IP.Text.Trim());

            //获取本地Port
            int port = int.Parse(this.txt_Port.Text.Trim());

            //创建本地网络节点
            IPEndPoint localEP = new IPEndPoint(ip, port);

            try
            {
                //将本地网络节点关联到用于监听的Socket套接字
                serverSocket.Bind(localEP);
            }
            catch (Exception ex)
            {
                //写入日志
                AddLog("服务开启失败" + ex.Message, 2);


            }
            

            serverSocket.Listen(10);



            //开启用于监听连接的线程
            Task.Run(new Action(() =>
            {
                ListenConnect();
            }));

2、监听客户端的连接

private void ListenConnect()
        {
            //一直处于监听状态
            while (true)
            {
              
                //一旦监听到连接,就返回一个客户端的Socket套接字
                Socket clientSocket = serverSocket.Accept();
                string  remoteEP = clientSocket.RemoteEndPoint.ToString();

                //写入日志
                AddLog(remoteEP + " 上线了", 0);

                //更新在线列表
                UpdateOnLine(remoteEP, true);

                //保存客户端对象
                dicSocket.Add(remoteEP, clientSocket);

                //开启用于接收数据的线程
                Task.Run(new Action(()=>
                {
                    reveiveMsg(clientSocket);
                }));


            }
        }

3、数据接收

   private void reveiveMsg(Socket clientSocket)
        {
            while (true)
            {
                //定义5M的数据缓存区
                byte[] rcvBuffer = new byte[1024 * 1024 * 5];

                int length = -1;

                string remoteEP = clientSocket.RemoteEndPoint.ToString();


                try
                {
                  length = clientSocket.Receive(rcvBuffer);
                }
                catch (Exception)
                {
                    //更新在线列表
                    UpdateOnLine(remoteEP, false);

                    //写入日志
                    AddLog(remoteEP + " 下线了", 0);

                    //删除客户端对象
                    dicSocket.Remove(remoteEP);

                    break;
                }


                if (length==0)
                {
                    //更新在线列表
                    UpdateOnLine(remoteEP, false);

                    //写入日志
                    AddLog(remoteEP + " 下线了", 0);

                    //删除客户端对象
                    dicSocket.Remove(remoteEP);

                    break;
                }
                else
                {
                    string rcvString = Encoding.UTF8.GetString(rcvBuffer, 0, length);

                    //写入日志
                    AddLog("[接收]"+rcvString, 0);
                }
                
            }
        }

4、数据发送

//处理需要发送的内容
            string sendString = this.txt_Send.Text.Trim();
            byte[] sendBuffer = Encoding.UTF8.GetBytes(sendString);

            //验证
            if (this.lb_OnLine.SelectedItem==null)
            {
                MessageBox.Show("请选择要发送内容的客户端","发送提示");
                return;
            }

            //发送
            foreach (string item in this.lb_OnLine.SelectedItems)
            {
                dicSocket[item].Send(sendBuffer);

                //写入日志
                AddLog("[发送]:"+item+" "+sendString, 0);
            }

        }

二、TCP/IP客户端

1、建立与服务器的连接

 //初始化客户端的Socket套接字
            clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

            //创建远程主机的网路节点
            IPAddress ip = IPAddress.Parse(this.txt_IP.Text.Trim());
            int port = int.Parse(this.txt_Port.Text.Trim());
            IPEndPoint serverEP = new IPEndPoint(ip, port);

            try
            {
                //客户端连接远程让那个主机网络节点
                clientSocket.Connect(serverEP);
            }
            catch (Exception ex)
            {
                //写入日志
                AddLog("与服务器连接失败," + ex.Message, 2);
            }


            //写入日志
            AddLog("与服务器连接成功", 0);

            //开启数据接收线程
            Task.Run(new Action(() =>
            receiveMsg()));

2、断开与服务器的连接

clientSocket?.Close();

3、接收数据

 while (true)
            {
                //定义5M的数据缓存区
                byte[] rcvBuffer = new byte[1024 * 1024 * 5];

                int length = -1;

                string remoteEP = clientSocket.RemoteEndPoint.ToString();


                try
                {
                    length = clientSocket.Receive(rcvBuffer);
                }
                catch (Exception)
                {
                   
                   

                    break;
                }


                if (length == 0)
                {
                    

                   

                    break;
                }
                else
                {
                    string rcvString = Encoding.UTF8.GetString(rcvBuffer, 0, length);

                    //写入日志
                    AddLog("[接收]:" + rcvString, 0);
                }

            }

4、发送数据

//处理要发送的数据
            string sendString = this.txt_Send.Text.Trim();
            byte[] sendBuffer = Encoding.ASCII.GetBytes(sendString);

            byte[] newBuffer = new byte[sendBuffer.Length + 1];
            Array.Copy(sendBuffer, 0, newBuffer, 1,sendBuffer.Length);

            newBuffer[0] = (byte)MsgType.ASCII;


            //发送数据
            clientSocket?.Send(newBuffer);

5、日志信息

  private string CurrentTime
        {
            get { return DateTime.Now.ToString("HH:mm:ss"); }

        }

        private void AddLog(string msg, int index)
        {
            if (!this.lv_Receive.InvokeRequired)
            {
                ListViewItem lvItem = new ListViewItem(" " + CurrentTime, index);
                lvItem.SubItems.Add(msg);
                //this.lv_Receive.Items.Insert(0, lvItem);//插入到最顶层

                this.lv_Receive.Items.Add(lvItem);

            }
            else
            {
                this.Invoke(new Action(() =>
                {
                    ListViewItem lvItem = new ListViewItem(" " + CurrentTime, index);
                    lvItem.SubItems.Add(msg);
                    //this.lv_Receive.Items.Insert(0, lvItem);//插入到最顶层

                    this.lv_Receive.Items.Add(lvItem);

                }));
            }
        }
原文地址:https://www.cnblogs.com/GaoGeBlog/p/13274307.html