.NET Socket通信

server 端
csharp 复制代码
Socket serverSocket = null;
        Socket ClientSocket = null;
        List<Socket> listSocket=new List<Socket>();

        private void btnlisten_Click(object sender, EventArgs e)
        {
            serverSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
            IPAddress ip = IPAddress.Parse(txtIP.Text);
            IPEndPoint endpoint = new IPEndPoint(ip, int.Parse(txtPort.Text));
            serverSocket.Bind(endpoint);
            //同时监控几个客户端
            serverSocket.Listen(10);
            Task.Run((Action)ListentConnectSocket);//等价于 Action action=ListentConnectSocket;Task.Run(action);
            //方法2
            //Thread thd = new Thread(ListentConnectSocket);
            //thd.IsBackground = true;
            //thd.Start();
        }
       
        void ListentConnectSocket()
        {
            // 死循环
            while (true)
            {              
                try
                {
                    ClientSocket = serverSocket.Accept(); //放在UI线程,会阻塞,所以放在另外一个线程
                   
                    string sendMsg = "恭喜您,服务器连接成功!";
                    ClientSocket.Send(Encoding.Default.GetBytes(sendMsg));
                    //客户端IP、端口号
                    string ClientInfo = ClientSocket.RemoteEndPoint.ToString();
                    //方法1
                    //Action<string> action = delegate (string msg)
                    //{
                    //    lsReceive.Items.Add(msg);
                    //};
                    //lsReceive.Invoke(action, ClientInfo);
                    //方法2 匿名方法
                    //lsReceive.Invoke((Action<string>)delegate(string msg) {
                    //    lsReceive.Items.Add(msg);
                    //},ClientInfo);
                    // 方法3 lamda
                    lsReceive.Invoke(new Action<string>((msg) =>
                    {
                        listSocket.Add(ClientSocket);
                        lsReceive.Items.Add($"{msg} 上线啦");
                    }), ClientInfo);
                }
                catch (Exception ex)
                {

                    lsReceive.Invoke(new Action<string>((msg) =>
                    {
                        lsReceive.Items.Add(msg);
                    }), $"发送信息失败;{ex.Message}");
                    break;
                }
               

                //开启接收信息
                //方法1
                //Thread thr = new Thread(ReceiveClientMsg);
                //thr.IsBackground = true;
                //thr.Start(ClientSocket);
                //方法2
                Action<Socket> action = new Action<Socket>(ReceiveClientMsg);
                Task.Run(()=>action(ClientSocket));
              
            }
        }
        private void ReceiveClientMsg(object clientSocket)
        {
            Socket client = clientSocket as Socket;
            while (true)
            {
                byte[] recBuffer = new byte[1024];
                int length = -1;
                try
                {
                    //Receive 是阻塞方法
                    length = client.Receive(recBuffer);
                }
                catch (Exception ex)
                {
                    //客户端关闭应用程序
                    string str = client.RemoteEndPoint.ToString();
                    this.Invoke(new Action(() =>
                    {
                        lsReceive.Items.Add($"接收客户端:{str} 异常; {ex.Message}");
                    }));
                    break;
                }
                if (length == 0)
                {
                    string str = client.RemoteEndPoint.ToString();
                    this.Invoke(new Action(() =>
                    {
                        lsReceive.Items.Add($"{str}:下线了!");
                    }));
                    break;
                }
                else
                {
                    string msg = Encoding.Default.GetString(recBuffer, 0, length);
                    string msgStr = $"{DateTime.Now}【 接收客户端: {client.RemoteEndPoint.ToString()}】--- {msg}";
                    this.Invoke(new Action(() =>
                    {
                        lsReceive.Items.Add(msgStr + Environment.NewLine);
                    }));
                }
            }
        }

        private void btnSend_Click(object sender, EventArgs e)
        {

            Task.Run(new Action(()=> {
                foreach (Socket item in listSocket)
                {
                    item.Send(Encoding.Default.GetBytes(txtSend.Text));
                }
              
            }));
            
        }

客户端

csharp 复制代码
  // 创建 Socket对象
        Socket clientSocket = null;
        private void btnConnect_Click(object sender, EventArgs e)
        {
            clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            IPEndPoint endPoint = new IPEndPoint(IPAddress.Parse(txtIP.Text), int.Parse(txtPort.Text));
            try
            {
                lstReceive.Items.Add("与服务器连接中。。。。");
                clientSocket.Connect(endPoint);
                //方法1
                Action action = ReceiveMsg;
                Task.Run(action);//开启线程
                if (clientSocket.Connected)
                {
                    lstReceive.Items.Add("服务器连接成功。。。。");
                }
                //方法2
                //Thread thd = new Thread(ReceiveMsg);
                //thd.IsBackground = true;
                //thd.Start();
            }
            catch (Exception ex)
            {
                lstReceive.Items.Add($"连接失败:{ ex.ToString()}");
            }
        }
        /// <summary>
        /// 接收消息
        /// </summary>
        private void ReceiveMsg()
        {
            while (true)
            {
                //声明接受最大字节数
                byte[] buffer = new byte[1024];
                int length = -1;
                try
                {
                    length = clientSocket.Receive(buffer);
                }
                catch (Exception ex)
                {
                    lstReceive.Invoke(new Action(() =>
                    {
                        lstReceive.Items.Add($"接收数据失败: {ex.Message}");
                    }));
                    break;
                }              
                if (length > 0)
                {
                    // 方法1
                    //byte[] temp = new byte[length];
                    //Array.Copy(buffer, 0, temp, 0, length);
                    //lstReceive.Invoke(new Action(() =>
                    //{
                    //    lstReceive.Items.Add(Encoding.UTF8.GetString(temp));
                    //}));
                    // 方法2
                    string msg = Encoding.Default.GetString(buffer,0,length);
                    lstReceive.Invoke(new Action(()=> {
                        lstReceive.Items.Add(msg);
                    }));
                }
            }
        }

        private void btnSend_Click(object sender, EventArgs e)
        {
            byte[] temp = Encoding.Default.GetBytes(textBox3.Text);
            try
            {
                clientSocket.Send(temp);
            }
            catch (Exception ex)
            {
                lstReceive.Items.Add($" 消息发送失败:{ex.Message}");
            }
           
        }
server 指定客户端发送信息
csharp 复制代码
   Socket serverSocket = null;
   Socket ClientSocket = null;
   //List<Socket> listSocket=new List<Socket>();
   //存储所有监控的客户端
   Dictionary<EndPoint,Socket> clientSocketDic=new Dictionary<EndPoint, Socket> ();
   private void btnlisten_Click(object sender, EventArgs e)
   {
       serverSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
       IPAddress ip = IPAddress.Parse(txtIP.Text);
       IPEndPoint endpoint = new IPEndPoint(ip, int.Parse(txtPort.Text));
       serverSocket.Bind(endpoint);
       //同时监控几个客户端
       serverSocket.Listen(10);
       Task.Run((Action)ListentConnectSocket);//等价于 Action action=ListentConnectSocket;Task.Run(action);
       //方法2
       //Thread thd = new Thread(ListentConnectSocket);
       //thd.IsBackground = true;
       //thd.Start();
   }
  
   void ListentConnectSocket()
   {
       // 死循环
       while (true)
       {              
           try
           {
               ClientSocket = serverSocket.Accept(); //放在UI线程,会阻塞,所以放在另外一个线程
              
               string sendMsg = "恭喜您,服务器连接成功!";
               ClientSocket.Send(Encoding.Default.GetBytes(sendMsg));
               //客户端IP、端口号
               string ClientInfo = ClientSocket.RemoteEndPoint.ToString();
               //方法1
               //Action<string> action = delegate (string msg)
               //{
               //    lsReceive.Items.Add(msg);
               //};
               //lsReceive.Invoke(action, ClientInfo);
               //方法2 匿名方法
               //lsReceive.Invoke((Action<string>)delegate(string msg) {
               //    lsReceive.Items.Add(msg);
               //},ClientInfo);
               // 方法3 lamda
               lsReceive.Invoke(new Action<string>((msg) =>
               {
                   clientSocketDic.Add(ClientSocket.RemoteEndPoint,ClientSocket);
                   comboBox1.Items.Add(ClientSocket.RemoteEndPoint);
                   lsReceive.Items.Add($"{msg} 上线啦");
               }), ClientInfo);
           }
           catch (Exception ex)
           {

               lsReceive.Invoke(new Action<string>((msg) =>
               {
                   lsReceive.Items.Add(msg);
               }), $"发送信息失败;{ex.Message}");
               break;
           }
          

           //开启接收信息
           //方法1
           //Thread thr = new Thread(ReceiveClientMsg);
           //thr.IsBackground = true;
           //thr.Start(ClientSocket);
           //方法2
           Action<Socket> action = new Action<Socket>(ReceiveClientMsg);
           Task.Run(()=>action(ClientSocket));
         
       }
   }
   private void ReceiveClientMsg(object clientSocket)
   {
       Socket client = clientSocket as Socket;
       while (true)
       {
           byte[] recBuffer = new byte[1024];
           int length = -1;
           try
           {
               //Receive 是阻塞方法
               length = client.Receive(recBuffer);
           }
           catch (Exception ex)
           {
               //客户端关闭应用程序
               string str = client.RemoteEndPoint.ToString();
               this.Invoke(new Action(() =>
               {
                   lsReceive.Items.Add($"接收客户端:{str} 异常; {ex.Message}");
               }));

               break;
           }
           if (length == 0)
           {
               string str = client.RemoteEndPoint.ToString();
               this.Invoke(new Action(() =>
               {
                   lsReceive.Items.Add($"{str}:下线了!");
               }));
               break;
           }
           else
           {
               string msg = Encoding.Default.GetString(recBuffer, 0, length);
               string msgStr = $"{DateTime.Now}【 接收客户端: {client.RemoteEndPoint.ToString()}】--- {msg}";
               this.Invoke(new Action(() =>
               {
                   lsReceive.Items.Add(msgStr + Environment.NewLine);
               }));
           }
       }
   }

   private void btnSend_Click(object sender, EventArgs e)
   {
      
           if (comboBox1.Text != string.Empty) 
           {
               string[] str=comboBox1.Text.Split(':');
               IPEndPoint endpoint=new IPEndPoint(IPAddress.Parse(str[0]), int.Parse(str[1]));
               Socket cltsocket = clientSocketDic[endpoint];
               Task.Run(new Action(() => {                                  
                   cltsocket.Send(Encoding.Default.GetBytes(txtSend.Text));
               }));
           }

             
       
   }



如何保证数据接受完整的方式
  1. 校验 双方协商 每次发信息,以什么符号结尾
  2. 包头+报文 双方协商 每次发信息,以什么符号、开始 、结尾
  3. 指令长度
数据获取的方式
  1. PC缓存区
  2. C# 操作获取数据
  3. 缓存区自移动

比较详细的概念:https://www.cnblogs.com/whuanle/p/10375526.html

相关推荐
WineMonk9 小时前
.NET WPF CommunityToolkit.Mvvm框架
.net·wpf·mvvm
界面开发小八哥9 小时前
界面控件DevExpress WPF中文教程:Data Grid——卡片视图设置
.net·wpf·界面控件·devexpress·ui开发
九鼎科技-Leo20 小时前
了解 .NET 运行时与 .NET 框架:基础概念与相互关系
windows·c#·.net
九鼎科技-Leo1 天前
什么是 ASP.NET Core?与 ASP.NET MVC 有什么区别?
windows·后端·c#·asp.net·mvc·.net
.net开发1 天前
WPF怎么通过RestSharp向后端发请求
前端·c#·.net·wpf
九鼎科技-Leo1 天前
在 C# 中,ICollection 和 IList 接口有什么区别?
windows·c#·.net
时光追逐者1 天前
C#/.NET/.NET Core学习路线集合,学习不迷路!
开发语言·学习·c#·asp.net·.net·.netcore·微软技术
Crazy Struggle1 天前
.NET 全功能流媒体管理控制接口平台
.net·开源项目·流媒体
.net开发1 天前
WPF使用prism框架发布订阅实现消息提示
c#·.net·wpf