基于TCP的Socket异步

Socket通讯还是比较实用的,目前研究阶段,demo也存在需要完善的地方。demo中实现了,客户端发送数据给服务端,服务端回复客户端消息。服务端主动给客户端发送消息。先上图看效果:

 

 服务端

界面简单明了

启动

开启监听,准备接受

 private void btnStart_Click(object sender, EventArgs e)
        {
            Thread thread = new Thread(StartListening);
            thread.Start();
        }

 

   private void StartListening()
        {
            IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
            // IPAddress ipAddress = ipHostInfo.AddressList[0];
            IPAddress.TryParse(txtIp.Text, out IPAddress ipAddress);
            int port = Convert.ToInt32(txtPort.Text);
            IPEndPoint localEndPoint = new IPEndPoint(ipAddress, port);
            listener = new Socket(ipAddress.AddressFamily,
                SocketType.Stream, ProtocolType.Tcp);

            try
            {
                listener.Bind(localEndPoint);
                listener.Listen(100);
                while (true)
                {
                    listener.BeginAccept(
                        new AsyncCallback(AcceptCallback),
                        listener);
                }

            }
            catch (Exception ex)
            {
                return;
            }
        }
   private void AcceptCallback(IAsyncResult ar)
        {
            // Get the socket that handles the client request.  
            //获取处理客户端请求的套字节
            listener = (Socket)ar.AsyncState;
            handler = listener.EndAccept(ar);
            handler.BeginReceive(buffer, 0, BufferSize, 0,
                new AsyncCallback(ReadCallback), handler);
        }

 处理收到的数据,send相当于回复客户端

  private void ReadCallback(IAsyncResult ar)
        {
            String content = String.Empty;
            handler = (Socket)ar.AsyncState;
            int bytesRead = handler.EndReceive(ar);
            if (bytesRead > 0)
            {
                // There  might be more data, so store the data received so far.  
                sb.Append(Encoding.Default.GetString(
                   buffer, 0, bytesRead));
                content = sb.ToString();
                if (content.Length > 0)
                {
                    this.Invoke((EventHandler)delegate
                    {
                        txtRecive.Text = content;
                    });
                    Send(handler, "服务端收到数据");

                }
                handler.BeginReceive(buffer, 0, BufferSize, 0,
                new AsyncCallback(ReadCallback), handler);
            }
        }

服务端主动发送:

  private void btnSend_Click(object sender, EventArgs e)
        {
            Send(handler, txtSend.Text);
        }
        /// <summary>
        /// 服务端回复客户端
        /// </summary>
        /// <param name="handler"></param>
        /// <param name="data"></param>
        private static void Send(Socket handler, String data)
        {
            // Convert the string data to byte data using ASCII encoding.  
            byte[] byteData = Encoding.Default.GetBytes(data);

            // Begin sending the data to the remote device.  
            handler.BeginSend(byteData, 0, byteData.Length, 0,
                new AsyncCallback(SendCallback), handler);
        }
        /// <summary>
        /// 发送回到
        /// </summary>
        /// <param name="ar"></param>
        private static void SendCallback(IAsyncResult ar)
        {
            try
            {
                Socket handler = (Socket)ar.AsyncState;
                int bytesSent = handler.EndSend(ar);
                Console.WriteLine("发送 {0} 字节到客户端.", bytesSent);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }

客户端

客户端主动连接服务端,并向服务端发送消息

 private void StartClient() 
        {
            //绑定端口和地址
            IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
            IPAddress.TryParse(txtIp.Text, out IPAddress ipAddress);
            int port = Convert.ToInt32(txtPort.Text);
            IPEndPoint remoteEP = new IPEndPoint(ipAddress, port);
            //创建客户端
            client = new Socket(ipAddress.AddressFamily,
                    SocketType.Stream, ProtocolType.Tcp);
            //开始连接
           IAsyncResult result= client.BeginConnect(remoteEP,
                    new AsyncCallback(ConnectCallback), client);
        }
        /// <summary>
        /// 连接回调
        /// </summary>
        /// <param name="ar"></param>
        private void ConnectCallback(IAsyncResult ar)
        {
            try
            {
               
                Socket client = (Socket)ar.AsyncState;
                client.EndConnect(ar);
                this.Invoke((EventHandler)delegate
                {
                    txtRecive.Text = string.Format("连接成功。。。", client.RemoteEndPoint.ToString());
                });
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }

发送和接收的函数及回调

 private void btnSend_Click(object sender, EventArgs e)
        {
            Send(client, txtSend.Text);
           // sendDone.WaitOne();
            Receive(client);
        }
        /// <summary>
        /// 接收服务端消息,
        /// 不需要接收,可以不调用
        /// </summary>
        /// <param name="socket"></param>
        private void Receive(object socket)
        {
            try
            {
                Socket client = (Socket)socket;
                client.BeginReceive(buffer, 0, BufferSize, 0,
                    new AsyncCallback(ReceiveCallback), client);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }
        /// <summary>
        /// 收到消息的回调
        /// </summary>
        /// <param name="ar"></param>
        private void ReceiveCallback(IAsyncResult ar)
        {
            try
            {
               
                Socket client = (Socket)ar.AsyncState;
                String content = String.Empty;
                // Read data from the remote device.  
                int bytesRead = client.EndReceive(ar);

                if (bytesRead > 0)
                {
                    // There might be more data, so store the data received so far.  
                    sb.Append(Encoding.Default.GetString(buffer, 0, bytesRead));
                    content = sb.ToString();
                    // Get the rest of the data.  
                    client.BeginReceive(buffer, 0, BufferSize, 0,
                        new AsyncCallback(ReceiveCallback), client);

                    // All the data has arrived; put it in response.  
                    if (content.Length > 0)
                    {
                        this.Invoke((EventHandler)delegate
                        {
                            txtRecive.AppendText("/r/n" + content);
                        });
                    }
                }
               
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }

        private void Send(Socket client, string data)
        {
            byte[] byteData = Encoding.Default.GetBytes(data);

            // Begin sending the data to the remote device.  
            client.BeginSend(byteData, 0, byteData.Length, 0,
                new AsyncCallback(SendCallback), client);
        }
        /// <summary>
        /// 发送消息回调
        /// </summary>
        /// <param name="ar"></param>
        private void SendCallback(IAsyncResult ar)
        {
            try
            {
               
                Socket client = (Socket)ar.AsyncState;
                int bytesSent = client.EndSend(ar);
                Console.WriteLine("发送 {0}字节到服务端.", bytesSent);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }

里面有些bug是没有处理的,像服务端断开,客户端重连报错。客户端断开,服务端发送数据失败处理等。

源码下载

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

90e家

有C币的小伙伴可以贡献一点,哈

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值