1. 程式人生 > WINDOWS開發 >C#上位機之—WinForm實現Socket非同步通訊示例

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,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,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,null);
        }
        public void OnDataReceived(IAsyncResult asyn)
        {
            int dataLenth = socClient.EndReceive(asyn);
            byte[] chars = new byte[dataLenth];
            Buffer.BlockCopy(dataReceived,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通訊模型已經完成,實際應用中還需考慮通訊異常,通訊協議,多個客戶端通訊等事項,第一次寫博,歡迎大家多多指正;