国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

C#異步的Socket通信(重構(gòu)局域網(wǎng)聊天小工具)

2019-11-17 03:35:48
字體:
供稿:網(wǎng)友

簡要說明
        上圖左邊部分表示的是客戶端的過程, 右邊部分表示的是服務(wù)端的過程. 客戶端相比服務(wù)端在建立連接之前步驟稍微少一些, 成功建立連接后客戶端和服務(wù)端都有一個CommunicateSocket負(fù)責(zé)與對方通信, 如發(fā)送消息, 接收消息, 發(fā)送文件, 接收文件等.

        服務(wù)端, 聲明ServerSocket, 綁定(Bind)一個ip并指定這個IP的通信端口, 比如是127.0.0.1:9050, ServerSocket可以監(jiān)聽來自多個IP發(fā)送的連接請求, 監(jiān)聽(Listen)方法的參數(shù)可以設(shè)置允許的最多連接請求個數(shù). 然后調(diào)用異步接受請求的方法(BeginAccept), 如果接受到某個客戶端發(fā)來連接請求, 這時定義一個新的CommunicateSocket專門負(fù)責(zé)與這個客戶端通信. 然后可以通過CommunicateSocket.BeginSend()方法給客戶端發(fā)送數(shù)據(jù), CommunicateSocket.BeginReceive()可以接收客戶端發(fā)來的數(shù)據(jù).

        客戶端, 有一個CommunicateSocket, 并綁定一個IP以及一個未被占用的端口, 定義IPEndPoint serverIP表示服務(wù)端Socket的IP和端口, 這樣才可以進(jìn)行端口對端口之間的通信, 接下來就可以嘗試CommunicateSocket.BeginConnect(serverIP), 連接成功之后就可以發(fā)送和接收數(shù)據(jù)了, CommunicateSocket.BeginSend(), CommunicateSocket.BeginReceive().

        有些異步方法有兩種實現(xiàn)方式, 如BeginAccept()和AcceptAsync(), 這兩個方法有什么區(qū)別呢?  以 Begin 和 End 開頭的方法是以 APM(Asynchronous PRogramming Model)設(shè)計方法實現(xiàn)的異步操作, 以 Async 結(jié)尾的方法是利用稱為 EAP (Event-based Asynchronous Pattern) 的設(shè)計方法實現(xiàn)的異步操作.

代碼部分
1. SocketFunc類
        SocketFunc是一個抽象類, 服務(wù)端和客戶端只有建立連接的方法不同, 其它都相同, 所以把相同的部分放到這個類中.

00 public abstract class SocketFunc 

01 { 

02     //不管是服務(wù)端還是客戶端, 建立連接后用這個Socket進(jìn)行通信 

03     public Socket communicateSocket = null; 

04   

05     //服務(wù)端和客戶端建立連接的方式稍有不同, 子類會重載 

06     public abstract void access(string IP, System.Action AccessAciton); 

07   

08     //發(fā)送消息的函數(shù) 

09     public void Send(string message) 

10     { 

11         if (communicateSocket.Connected == false) 

12         { 

13             throw new Exception("還沒有建立連接, 不能發(fā)送消息"); 

14         } 

15         Byte[] msg = Encoding.UTF8.GetBytes(message); 

16         communicateSocket.BeginSend(msg,0, msg.Length, SocketFlags.None, 

17             ar => { 

18                   

19             }, null); 

20     } 

21   

22     //接受消息的函數(shù) 

23     public void Receive(System.Action<string> ReceiveAction) 

24     { 

25         //如果消息超過1024個字節(jié), 收到的消息會分為(總字節(jié)長度/1024 +1)條顯示 

26         Byte[] msg = new byte[1024]; 

27         //異步的接受消息 

28         communicateSocket.BeginReceive(msg, 0, msg.Length, SocketFlags.None, 

29             ar => { 

30                 //對方斷開連接時, 這里拋出Socket Exception 

31                 //An existing connection was forcibly closed by the remote host  

32                     communicateSocket.EndReceive(ar);  

33                 ReceiveAction(Encoding.UTF8.GetString(msg).Trim('/0',' ')); 

34                 Receive(ReceiveAction); 

35             }, null); 

36     } 

37 }

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

00 public class ServerSocket:SocketFunc 

01 { 

02     //服務(wù)端重載Access函數(shù) 

03     public override void Access(string IP, System.Action AccessAciton) 

04     { 

05         Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 

06         //本機(jī)預(yù)使用的IP和端口 

07         IPEndPoint serverIP = new IPEndPoint(IPAddress.Any, 9050); 

08         //綁定服務(wù)端設(shè)置的IP 

09         serverSocket.Bind(serverIP); 

10         //設(shè)置監(jiān)聽個數(shù) 

11         serverSocket.Listen(1); 

12         //異步接收連接請求 

13         serverSocket.BeginAccept(ar => 

14             { 

15                 base.communicateSocket = serverSocket.EndAccept(ar); 

16                 AccessAciton(); 

17             }, null); 

18     } 

19 }

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

00 public class ClientSocket:SocketFunc 

01 { 

02     //客戶端重載Access函數(shù) 

03     public override void Access(string IP, System.Action AccessAciton) 

04     { 

05         base.communicateSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 

06         base.communicateSocket.Bind(new IPEndPoint(IPAddress.Any, 9051)); 

07               

08         //服務(wù)器的IP和端口 

09         IPEndPoint serverIP; 

10         try

11         { 

12             serverIP = new IPEndPoint(IPAddress.Parse(IP), 9050); 

13         } 

14         catch

15         { 

16             throw new Exception(String.Format("{0}不是一個有效的IP地址!", IP)); 

17         } 

18               

19         //客戶端只用來向指定的服務(wù)器發(fā)送信息,不需要綁定本機(jī)的IP和端口,不需要監(jiān)聽 

20         try

21         { 

22             base.communicateSocket.BeginConnect(serverIP, ar => 

23             { 

24                 AccessAciton(); 

25             }, null); 

26         } 

27         catch

28         { 

29             throw new Exception(string.Format("嘗試連接{0}不成功!", IP)); 

30         } 

31     } 

32 }


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 龙门县| 云梦县| 铜川市| 浦城县| 库尔勒市| 平度市| 新郑市| 黄陵县| 洪江市| 驻马店市| 胶南市| 贡山| 徐水县| 承德市| 两当县| 酒泉市| 肇州县| 沁水县| 包头市| 田东县| 林甸县| 洛扎县| 饶河县| 塔城市| 西充县| 龙泉市| 绥棱县| 方正县| 丰原市| 共和县| 扎赉特旗| 平阴县| 姚安县| 刚察县| 白银市| 稷山县| 乌苏市| 东至县| 格尔木市| 永福县| 秀山|