C#,Socket通讯原理,附加源码解释(Socket服务端和客户端)

1、先启动服务端 IP和端口都为服务端
2、客户端连接到服务端 IP和端口都为服务端
3、客户端发送信息到服务端
以下是原理图

以下是Socket服务端核心代码
        //原创来自 http://www.luofenming.com/show.aspx?id=ART2018120700001
        /// <summary>
        /// 创建Scoket 服务端
        /// </summary>
        /// <param name="IP"></param>
        /// <param name="prot"></param>
        /// <returns></returns>
        public Socket CreateSocket(string IP, string prot)
        {
            //定义一个套接字用于监听客户端发来的信息  包含3个参数(IP4寻址协议,流式连接,TCP协议)
            Socket socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //发送信息 需要1个IP地址和端口号
            IPAddress ipaddress = IPAddress.Parse(IP); //获取文本框输入的IP地址
            //将IP地址和端口号绑定到网络节点endpoint上 
            IPEndPoint endpoint = new IPEndPoint(ipaddress, int.Parse(prot)); //获取文本框上输入的端口号
            //套接字点听绑定网络端点
            socketWatch.Bind(endpoint);
            //将套接字的监听队列长度设置为20
            socketWatch.Listen(20);
            return socketWatch;
        }

        /// <summary>
        /// 创建一个负责监听客户端的线程  并启动
        /// </summary>
        /// <returns></returns>
        public void CreateThread(Socket socket)
        {
            //创建一个负责监听客户端的线程 
            Thread threadWatch = new Thread(new ParameterizedThreadStart(WatchConnecting));
            //将窗体线程设置为与后台同步
            threadWatch.IsBackground = true;
            //启动线程
            threadWatch.Start(socket);
        }

        /// <summary>
        /// 持续不断监听客户端发来的请求, 用于不断获取客户端发送过来的连续数据信息
        /// </summary>
        private void WatchConnecting(object socket)
        {
            Socket socketWatch = socket as Socket;
            while (true)
            {
                Socket socConnection = null;
                try
                {
                    socConnection = socketWatch.Accept();
                    //((IPEndPoint)socConnection.RemoteEndPoint).Address.ToString();//获取客户端IP
                    //((IPEndPoint)socConnection.RemoteEndPoint).Port.ToString();//获取客户端端口
                }
                catch (Exception ex)
                {
                    break;//提示套接字监听异常  ex.Message   
                }
                //创建通信线程 
                ParameterizedThreadStart pts = new ParameterizedThreadStart(ServerRecMsg);
                Thread thr = new Thread(pts);
                thr.IsBackground = true;
                //启动线程 
                thr.Start(socConnection);
            }
        }

        /// <summary>
        /// 接收客户端发来的信息
        /// </summary>
        private void ServerRecMsg(object socketClientPara)
        {
            Socket socketServer = socketClientPara as Socket;
            int ReceiveBufferSize = 8 * 1024;
            while (true)
            {
                int firstReceived = 0;
                byte[] buffer = new byte[ReceiveBufferSize];
                try
                {
                    List<byte> ls = new List<byte>();
                    //获取接收的数据,并存入内存缓冲区  返回一个字节数组的长度
                    if (socketServer != null) firstReceived = socketServer.Receive(buffer);

                    if (firstReceived > 0) //接受到的长度大于0 说明有信息或文件传来
                    {
                        ls.AddRange(buffer.Skip(0).Take(firstReceived));

                        //对接收数据进行逻辑判断 回复客户端需要的数据
                        string msg = "接收成功" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "\r\n";
                        byte[] datas = System.Text.Encoding.UTF8.GetBytes(msg);
                        socketServer.Send(datas);//小数据可以一次性发送  如果大数据要分端发送 用while 循环
                    }
                }
                catch (Exception ex)
                {
                    break;  //捕获异常信息 ex.Message
                }
            }
        }

        //启动服务端
        private void button1_Click(object sender, EventArgs e)
        {
            //textBox1.Text 为服务端IP  textBox2.Text 为服务端端口
            Socket testSocket = CreateSocket(textBox1.Text, textBox2.Text);
            CreateThread(testSocket);
        }
以下是客户端核心代码
        //原创来自 http://www.luofenming.com/show.aspx?id=ART2018120700001
        /// <summary>
        /// 创建Scoket 客户端
        /// </summary>
        /// <param name="IP"></param>
        /// <param name="prot"></param>
        /// <returns></returns>
        public Socket CreateSocket(string IP, string prot)
        {
            //定义一个套接字用于监听客户端发来的信息  包含3个参数(IP4寻址协议,流式连接,TCP协议)
            Socket socketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //发送信息 需要1个IP地址和端口号
            IPAddress ipaddress = IPAddress.Parse(IP); //获取文本框输入的IP地址
            //将IP地址和端口号绑定到网络节点endpoint上 
            IPEndPoint endpoint = new IPEndPoint(ipaddress, int.Parse(prot)); //获取文本框上输入的端口号
            //向指定的ip和端口号的服务端发送连接请求 用的方法是Connect 不是Bind
            socketClient.Connect(endpoint);
            return socketClient;
        }
        /// <summary>
        /// 创建一个接收服务端发来信息的  线程并启动
        /// </summary>
        /// <param name="socket"></param>
        private void CreateThread(Socket socket)
        {
            //创建一个新线程 用于监听服务端发来的信息
            Thread threadClient = new Thread(RecMsg);
            //将窗体线程设置为与后台同步
            threadClient.IsBackground = true;
            //启动线程
            threadClient.Start(socket);
        }

        /// <summary>
        /// 接受服务端发来信息的方法
        /// </summary>
        private void RecMsg(object socket)
        {
            Socket socketClient = socket as Socket;
            int SendBufferSize = 2 * 1024;
            while (true) //持续监听服务端发来的消息
            {
                string strRecMsg = null;
                int length = 0;
                byte[] buffer = new byte[SendBufferSize];
                try
                {
                    length = socketClient.Receive(buffer);
                }
                catch (Exception ex)
                {
                    break;
                }
                //将套接字获取到的字节数组转换为人可以看懂的字符串
                strRecMsg = Encoding.UTF8.GetString(buffer, 0, length);
            }
        }
        Socket socket;

        /// <summary>
        /// 连接服务端
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            //textBox1.Text 为服务端IP  textBox2.Text 为服务端端口
            socket = CreateSocket(textBox1.Text, textBox2.Text);
            CreateThread(socket);
        }

        /// <summary>
        /// 发送信息到服务端
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            if (socket != null && socket.Connected)
            {
                socket.Send(new byte[] { 0x11, 0x22, 0x33, 0x44, 0x55 });
            }
        }

评论

  1. 222.84.24.*2020-09-25 17:01:26
    咋测试