zoukankan      html  css  js  c++  java
  • C#上位机之—WinForm实现Socket异步通讯示例

    工作中常用到的一些知识点,总是用完就忘,第一次尝试用博客记录下来,以备后用;

    Socket通讯,Socket(套接字)是基于TCP/IP通讯方式的封装好的类,调用时需要添加下面的服务引用:

    .......
    10 using System.Net; 11 using System.Net.Sockets;

    窗体页面搭建,上面为服务器区,下面为客户端区:

    建立两个类,一个表示服务器,一个表示客户端,

    首先建立服务器类:

    1.声明变量:IP地址,端口号,EndPoint,Socket类,数据Buffer等

     1         string ip;//IP地址
     2         string port;//端口号
     3         IPEndPoint endPoint;//网络端点
     4         Socket socServer;//侦听连接套接字
     5         Socket socClient;//通讯套接字
     6         byte[] dataReceived = new byte[50000];
     7 
     8         public delegate void delegateDisplayMsg(string type,string msg);
     9         public delegateDisplayMsg OnDisplay;
    10 
    11         public SocketServer()
    12         {
    13             socServer = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    14         }
    View Code

    2.侦听连接函数:

           public void StartListen(string ip,string port)
           {
                this.ip = ip;
                this.port = port;
                endPoint = new IPEndPoint(IPAddress.Parse(this.ip), int.Parse(port));
                socServer.Bind(endPoint);
                socServer.Listen(0);
                socServer.BeginAccept(new AsyncCallback(OnClientConnect), null);
                ShowMsg("Wait Connect");
            }
    View Code

    3.接受数据函数:

    public void OnClientConnect(IAsyncResult asyn)
            {
                socClient = socServer.EndAccept(asyn);
                WaitForData();
                ShowMsg("Client Connected  " + socClient.RemoteEndPoint.ToString());
            }
            public void WaitForData()
            {
                if (socClient != null)
                    socClient.BeginReceive(dataReceived, 0, dataReceived.Length, SocketFlags.None, new AsyncCallback(OnDataReceived), null);
            }
            public void OnDataReceived(IAsyncResult asyn)
            {
                int dataLength = socClient.EndReceive(asyn);
                byte[] chars = new byte[dataLength];
                Buffer.BlockCopy(dataReceived, 0, chars, 0, dataLength);
                string msg = Encoding.ASCII.GetString(chars);
                ShowMsg("<=" + msg);
                WaitForData();
            }
    View Code

    4.发送数据函数:

            public void SendMsg(string msg)
            {
                byte[] data = Encoding.Default.GetBytes(msg);
                socClient.Send(data);
                ShowMsg("=>" + msg);
            }
    View Code

    然后建立客户端类:

    1.声明变量

            string ip;//IP地址
            string port;//端口号
            IPEndPoint endPoint;//网络端点
            Socket socClient;//通讯套接字
            byte[] dataReceived = new byte[50000];//数据Buffer
    
            public delegate void delegateDisplayMsg(string type,string msg);
            public delegateDisplayMsg OnDisplay;
    
            public SocketClient()
            {
                socClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            }
    View Code

    2.连接服务器函数:

            public void Connect(string ip, string port)
            {
                this.ip = ip;
                this.port = port;
                endPoint = new IPEndPoint(IPAddress.Parse(this.ip), int.Parse(port));
                socClient.BeginConnect(endPoint, new AsyncCallback(OnToConnected), null);
            }
    View Code

    3.接受数据函数:

            public void OnToConnected(IAsyncResult asyn)
            {
                socClient.EndConnect(asyn);
                WaitForData();
                ShowMsg("Connect Success");
            }
            public void WaitForData()
            {
                if (socClient != null)
                    socClient.BeginReceive(dataReceived, 0, dataReceived.Length, SocketFlags.None, new AsyncCallback(OnDataReceived), null);
            }
            public void OnDataReceived(IAsyncResult asyn)
            {
                int dataLenth = socClient.EndReceive(asyn);
                byte[] chars = new byte[dataLenth];
                Buffer.BlockCopy(dataReceived, 0, chars, 0, dataLenth);
                string msg = Encoding.ASCII.GetString(chars);
                ShowMsg("<=" + msg);
                WaitForData();
            }
    View Code

    4.发送数据函数:

            public void SendMsg(string msg)
            {
                byte[] data = Encoding.Default.GetBytes(msg);
                socClient.Send(data);
                ShowMsg("=>" + msg);
            }
    View Code

    服务器类与客户端类,已经建立完成,下面对两个类进行实例化,并Link窗体控件的事件函数,如下:

    1.实例化:

    public void Init()
    {
         Server = new SocketServer();
         Client = new SocketClient();
         Server.OnDisplay += ShowMsg;
         Client.OnDisplay += ShowMsg;
    }

    2.按钮点击事件:

            private void btn_StartListen_Click(object sender, EventArgs e)
            {
                Server.StartListen(txt_serverIP.Text.ToString(), txt_serverPort.Text.ToString());
                btn_StartListen.BackColor = Color.LimeGreen;
            }
    
            private void btn_Connect_Click(object sender, EventArgs e)
            {
                Client.Connect(txt_clientIP.Text.ToString(), txt_clientPort.Text.ToString());
            }
    
            private void btn_serverSend_Click(object sender, EventArgs e)
            {
                Button b = (Button)sender;
                bool isServer = b.Name.Contains("server");
                if (isServer)
                    Server.SendMsg(txt_serverMsg.Text.ToString());
                else
                    Client.SendMsg(txt_clientMsg.Text.ToString());
            }
    View Code

    现在启动程序,测试发送接收功能是否正常

    至此,一个简单的Socket通讯模型已经完成,实际应用中还需考虑通讯异常,通讯协议,多个客户端通讯等事项,第一次写博,欢迎大家多多指正;

  • 相关阅读:
    Netty入门
    hashCode方法里为什么选择数字31作为生成hashCode值的乘数
    【转】String hashCode 方法为什么选择数字31作为乘子
    NppFTP小插件的使用
    事务的基础入门
    Code Review 程序员的寄望与哀伤【转载】
    谈谈敏捷开发【转载】
    如何写代码 — 编程内功心法【转载】
    面经【转载】
    Swagger的简单入门【转载】
  • 原文地址:https://www.cnblogs.com/treeskyer/p/12747547.html
Copyright © 2011-2022 走看看