基于Socket的Winform例子

一、直接上效果图

二、Socket握手

三、服务端

     Thread threadWatch = null;// 负责监听客户端的线程
        Socket socketWatch = null;// 负责监听客户端的套接字
        Socket clientConnection = null;// 负责和客户端通信的套接字
        private void btn_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(ipAddress.Text.ToString()))
            {
                MessageBox.Show("监听ip地址不能为空!");
                return;
            }
            if (string.IsNullOrEmpty(port.Text.ToString()))
            {
                MessageBox.Show("监听端口不能为空!");
                return;
            }
            // 定义一个套接字用于监听客户端发来的消息,包含三个参数(ipv4寻址协议,流式连接,tcp协议)
            socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            // 服务端发送消息需要一个ip地址和端口号
            IPAddress ip = IPAddress.Parse(ipAddress.Text.Trim());
            // 把ip地址和端口号绑定在网路节点endport上
            IPEndPoint endPort = new IPEndPoint(ip, int.Parse(port.Text.Trim()));
         
            // 监听绑定的网路节点
            socketWatch.Bind(endPort);
            // 将套接字的监听队列长度设置限制为0,0表示无限
            socketWatch.Listen(0);
            // 创建一个监听线程
            threadWatch = new Thread(WatchConnecting);
            threadWatch.IsBackground = true;
            threadWatch.Start();
            chatContent.AppendText("成功启动监听!ip:"+ip+",端口:"+port.Text.Trim()+"
");

        }

        /// <summary>
        ///  监听客户端发来的请求
        /// </summary>
        private void WatchConnecting()
        {
            //持续不断监听客户端发来的请求
            while (true)
            {
                clientConnection = socketWatch.Accept();
                chatContent.AppendText("客户端连接成功!"+"
");
                // 创建一个通信线程
                ParameterizedThreadStart pts = new ParameterizedThreadStart(acceptMsg);
                Thread thr = new Thread(pts);
                thr.IsBackground = true;
                thr.Start(clientConnection);
            }
        }

        /// <summary>
        ///  接收客户端发来的消息
        /// </summary>
        /// <param name="socket">客户端套接字对象</param>
        private void acceptMsg(object socket)
        {
            Socket socketServer = socket as Socket;
            while (true)
            {
                //创建一个内存缓冲区 其大小为1024*1024字节  即1M
                byte[] recMsg = new byte[1024 * 1024];
                //将接收到的信息存入到内存缓冲区,并返回其字节数组的长度
                int length = socketServer.Receive(recMsg);
                //将机器接受到的字节数组转换为人可以读懂的字符串
                string msg = Encoding.UTF8.GetString(recMsg,0,length);
                chatContent.AppendText("客户端("+GetCurrentTime()+"):"+msg+"
");
            }
        }
        /// <summary>
        ///  发送消息到客户端
        /// </summary>
        /// <param name="msg"></param>
        private void serverSendMsg(string msg)
        {
            byte[] sendMsg = Encoding.UTF8.GetBytes(msg);
            clientConnection.Send(sendMsg);
            chatContent.AppendText("服务端("+GetCurrentTime()+"):"+msg+"
");
        }

        /// <summary>
        /// 获取当前系统时间的方法
        /// </summary>
        /// <returns>当前时间</returns>
        private DateTime GetCurrentTime()
        {
            DateTime currentTime = new DateTime();
            currentTime = DateTime.Now;
            return currentTime;
        }

四、客户端

      // 创建一个客户端套接字
        Socket clientSocket = null;
        // 创建一个监听服务端的线程
        Thread threadServer = null;
        private void btn_Click(object sender, EventArgs e)
        {
            clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            if (string.IsNullOrEmpty(ipAddress.Text.ToString()))
            {
                MessageBox.Show("监听ip地址不能为空!");
                return;
            }
            if (string.IsNullOrEmpty(port.Text.ToString()))
            {
                MessageBox.Show("监听端口不能为空!");
                return;
            }
            IPAddress ip = IPAddress.Parse(ipAddress.Text.Trim());
            IPEndPoint endpoint = new IPEndPoint(ip, int.Parse(port.Text.Trim()));
         
            try
            {   //这里客户端套接字连接到网络节点(服务端)用的方法是Connect 而不是Bind
                clientSocket.Connect(endpoint);
            }
            catch 
            {
                chatContent.AppendText("连接失败!");
               
            }
            
            // 创建一个线程监听服务端发来的消息
            threadServer = new Thread(recMsg);
            threadServer.IsBackground = true;
            threadServer.Start();
        }

        /// <summary>
        ///  接收服务端发来的消息
        /// </summary>
        private void recMsg() {

            while (true) //持续监听服务端发来的消息
            {
                //定义一个1M的内存缓冲区 用于临时性存储接收到的信息
                byte[] arrRecMsg = new byte[1024 * 1024];
                int length = 0;
                try
                {
                    //将客户端套接字接收到的数据存入内存缓冲区, 并获取其长度
                     length = clientSocket.Receive(arrRecMsg);
                }
                catch 
                {
                    return;
                   
                }
             
                //将套接字获取到的字节数组转换为人可以看懂的字符串
                string strRecMsg = Encoding.UTF8.GetString(arrRecMsg, 0, length);
                //将发送的信息追加到聊天内容文本框中
                chatContent.AppendText("服务端(" + GetCurrentTime() + "):" + strRecMsg + "
");
            }
        }

        /// <summary>
        /// 发送消息到服务端
        /// </summary>
        /// <param name="msg"></param>
        private void clientSendMsg(string msg)
        {
            byte[] sendMsg = Encoding.UTF8.GetBytes(msg);
            clientSocket.Send(sendMsg);
            chatContent.AppendText("客户端(" + GetCurrentTime() + "):" + msg + "
");
        }
        /// <summary>
        /// 获取当前系统时间的方法
        /// </summary>
        /// <returns>当前时间</returns>
        private DateTime GetCurrentTime()
        {
            DateTime currentTime = new DateTime();
            currentTime = DateTime.Now;
            return currentTime;
        }

GitHub源码地址:https://github.com/51042309/Socket

原文地址:https://www.cnblogs.com/WangJunZzz/p/7655758.html