C#網(wǎng)絡(luò)通信:TCP連接
基本原理:TCP連接的特點(diǎn)是連接一直存在,即建立連接后可以隨時傳輸數(shù)據(jù),直至斷開連接為止。TCP連接有著明確的服務(wù)器和客戶端的分工,因此需要分別編程處理。
網(wǎng)絡(luò)通信用到的命名空間:
- using System.Net;
- using System.Net.Sockets;
C#網(wǎng)絡(luò)通信:TCP連接第一步——獲取服務(wù)器的IP地址
當(dāng)然您可以通過ipconfig等方式查詢作為服務(wù)器的計(jì)算機(jī)的IP地址,這里介紹通過C#語句獲取的方法。
- private String GetIPAddress()
- {
- String str;
- String Result = "";
- String hostName = Dns.GetHostName();
- IPAddress[] myIP = Dns.GetHostAddresses(hostName);
- foreach (IPAddress address in myIP)
- {
- str = address.ToString();
- for (int i = 0; i < str.Length; i++)
- {
- if (str[i] >= '0' && str[i] < = '9' || str[i] == '.') Result = str;
- }
- }
- return Result;
- }
紅色的部分是核心的語句,獲取的是一組IP地址,存儲在 IPAddress[] myIP 中。這組IP地址包含物理(依次輸出下就會發(fā)現(xiàn)),但我們最常用的是32位的IP地址,因此編寫了這個方法進(jìn)行篩選。
C#網(wǎng)絡(luò)通信:TCP連接第二步——服務(wù)器建立監(jiān)聽
- IPAddress ipa = IPAddress.Parse("192.168.1.100");
- TcpListener myListener = new TcpListener(ipa, 8080);
- myListener.Start();
紅色的部分是服務(wù)器的IP地址和要開放的端口號,視具體情況而定。端口號為整型。
C#網(wǎng)絡(luò)通信:TCP連接第三步——客戶端請求連接
- TcpClient tclient = new TcpClient();
- tclient.Connect("192.168.1.100", 8080);
如果客戶端請求連接時服務(wù)器并未開啟監(jiān)聽,則會拋出 SocketException 異常。所以一是要確保服務(wù)器開啟監(jiān)聽了再請求連接,二是應(yīng)該把這兩行代碼放入到try-catch里面,以便連接不成功時程序不會崩潰。
C#網(wǎng)絡(luò)通信:TCP連接第四步——服務(wù)器應(yīng)答
- Socket mySocket = myListener.AcceptSocket();
服務(wù)器將連接綁定給mySocket,以后和客戶端的通信都通過mySocket來完成。
但這里需要注意,如果執(zhí)行該語句時沒有客戶端請求連接,則會進(jìn)入無盡的等待,使程序出現(xiàn)“未響應(yīng)”的狀態(tài)。因此Socket的下面這個方法將極為有用:
- if (myListener.Pending())
- {
- Socket mySocket = myListener.AcceptSocket();
- }
Pending()的作用是“確定是否有掛起的連接請求”,如果有則返回true。這樣以來就實(shí)現(xiàn)了有請求時才去接受,再配合WinForm的Timer組件使用,可以達(dá)到很好的效果。
至此,連接工作已完成。總結(jié)一下,只有第三步是客戶端的代碼,其余都是服務(wù)器的代碼。
C#網(wǎng)絡(luò)通信:TCP連接第五步——發(fā)送數(shù)據(jù)和接收數(shù)據(jù)
1.服務(wù)器發(fā)送:
- mySocket.Send(Encoding.Unicode.GetBytes("要發(fā)送的內(nèi)容"));
2.服務(wù)器接收:
- byte[] data = new byte[1024];
- if (mySocket.Available > 0)
- {
- mySocket.Receive(data);
- String content = Encoding.Unicode.GetString(data);
- }
3.客戶端發(fā)送:
- NetworkStream ns = tclient.GetStream();
- String content = "要發(fā)送的內(nèi)容";
- byte[] data = Encoding.Unicode.GetBytes(content);
- ns.Write(data, 0, data.Length);
4.客戶端接受:
- if (tclient.Available > 0)
- {
- byte[] data = new byte[1024];
- ns.Read(data, 0, 1024);
- String content = Encoding.Unicode.GetString(data);
- }
服務(wù)器使用Send和Receive方法,客戶端使用NetworkStream流。其中 mySocket.Available > 0 和 tclient.Available > 0 的作用與 myListener.Pending() 的作用相同,都是先判斷是否有數(shù)據(jù)可讀再進(jìn)行讀取,否則也會失去響應(yīng)。Encoding.Unicode的方法用于字符串和字節(jié)數(shù)組間的轉(zhuǎn)換,因?yàn)榫W(wǎng)絡(luò)中的數(shù)據(jù)是以字節(jié)傳輸?shù)摹=邮諗?shù)據(jù)時也可以使用Timer來達(dá)到更好的效果。
【編輯推薦】