C#非同步Socket通訊(重構區域網路聊天小工具)

來源:互聯網
上載者:User

        五一在家看了一會兒<重構手冊>, 想拿以前寫的代碼嘗試著改進改進, 想起去年暑假寫的區域網路聊天小工具, 現在看自己那時寫的代碼已經不堪入目, 最不可思議的當屬用了"多線程"處理網路請求, 現在覺得應該使用非同步方法呼叫.

主要設計

簡要說明

        左邊部分表示的是用戶端的過程, 右邊部分表示的是服務端的過程. 用戶端相比服務端在建立串連之前步驟稍微少一些, 成功建立串連後用戶端和服務端都有一個CommunicateSocket負責與對方通訊, 如發送訊息, 接收訊息, 傳送檔案, 接收檔案等.

        服務端, 聲明ServerSocket, 綁定(Bind)一個IP並指定這個IP的通訊連接埠, 比如是127.0.0.1:9050, ServerSocket可以監聽來自多個IP發送的串連請求, 監聽(Listen)方法的參數可以設定允許的最多串連請求個數. 然後調用非同步接受請求的方法(BeginAccept), 如果接受到某個用戶端發來串連請求, 這時定義一個新的CommunicateSocket專門負責與這個用戶端通訊. 然後可以通過CommunicateSocket.BeginSend()方法給用戶端發送資料, CommunicateSocket.BeginReceive()可以接收用戶端發來的資料.

        用戶端, 有一個CommunicateSocket, 並綁定一個IP以及一個未被佔用的連接埠, 定義IPEndPoint serverIP表示服務端Socket的IP和連接埠, 這樣才可以進行連接埠對連接埠之間的通訊, 接下來就可以嘗試CommunicateSocket.BeginConnect(serverIP), 串連成功之後就可以發送和接收資料了, CommunicateSocket.BeginSend(), CommunicateSocket.BeginReceive().

        有些非同步方法呼叫有兩種實現方式, 如BeginAccept()和AcceptAsync(), 這兩個方法有什麼區別呢?  以 Begin 和 End 開頭的方法是以 APM(Asynchronous Programming Model)設計方法實現的非同步作業, 以 Async 結尾的方法是利用稱為 EAP (Event-based Asynchronous Pattern) 的設計方法實現的非同步作業.

代碼部分1. SocketFunc類

        SocketFunc是一個抽象類別, 服務端和用戶端只有建立串連的方法不同, 其它都相同, 所以把相同的部分放到這個類中.

public abstract class SocketFunc{    //不管是服務端還是用戶端, 建立串連後用這個Socket進行通訊    public Socket communicateSocket = null;    //服務端和用戶端建立串連的方式稍有不同, 子類會重載    public abstract void Access(string IP, System.Action AccessAciton);    //發送訊息的函數    public void Send(string message)    {        if (communicateSocket.Connected == false)        {            throw new Exception("還沒有建立串連, 不能發送訊息");        }        Byte[] msg = Encoding.UTF8.GetBytes(message);        communicateSocket.BeginSend(msg,0, msg.Length, SocketFlags.None,            ar => {                            }, null);    }    //接受訊息的函數    public void Receive(System.Action<string> ReceiveAction)    {        //如果訊息超過1024個位元組, 收到的訊息會分為(總位元組長度/1024 +1)條顯示        Byte[] msg = new byte[1024];        //非同步接受訊息        communicateSocket.BeginReceive(msg, 0, msg.Length, SocketFlags.None,            ar => {                //對方中斷連線時, 這裡拋出Socket Exception                //An existing connection was forcibly closed by the remote host                     communicateSocket.EndReceive(ar);                 ReceiveAction(Encoding.UTF8.GetString(msg).Trim('\0',' '));                Receive(ReceiveAction);            }, null);    }}
2. ServerSocket:SocketFunc類

        繼承自SocketFunc類, 類中重載了Access方法.

public class ServerSocket:SocketFunc{    //服務端重載Access函數    public override void Access(string IP, System.Action AccessAciton)    {        Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);        //本機預使用的IP和連接埠        IPEndPoint serverIP = new IPEndPoint(IPAddress.Any, 9050);        //綁定服務端設定的IP        serverSocket.Bind(serverIP);        //設定監聽個數        serverSocket.Listen(1);        //非同步接收串連請求        serverSocket.BeginAccept(ar =>            {                base.communicateSocket = serverSocket.EndAccept(ar);                AccessAciton();            }, null);    }}
3. ClientSocket:SocketFunc類

        繼承自SocketFunc類, 類中重載了Access方法.

public class ClientSocket:SocketFunc{    //用戶端重載Access函數    public override void Access(string IP, System.Action AccessAciton)    {        base.communicateSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);        base.communicateSocket.Bind(new IPEndPoint(IPAddress.Any, 9051));                    //伺服器的IP和連接埠        IPEndPoint serverIP;        try        {            serverIP = new IPEndPoint(IPAddress.Parse(IP), 9050);        }        catch        {            throw new Exception(String.Format("{0}不是一個有效IP地址!", IP));        }                    //用戶端只用來向指定的伺服器發送資訊,不需要綁定原生IP和連接埠,不需要監聽        try        {            base.communicateSocket.BeginConnect(serverIP, ar =>            {                AccessAciton();            }, null);        }        catch        {            throw new Exception(string.Format("嘗試串連{0}不成功!", IP));        }    }}
程式

   

源碼下載

       

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.