C#.Net Socket網絡通訊編程

1 、理解socket 
1) 、 
Socket 接口是TCP/IP 網絡的應用程序接口(API )。Socket 接口定義了許多函數和例程,程序員可以用它們來開發TCP/IP 網絡應用程序。Socket 可以看成是網絡通信上的一個端點,也就是說,網絡通信包括兩臺主機或兩個進程,通過網絡傳遞它們之間的數據。爲了進行網絡通信,程序在網絡對話的每一端都需要一個Socket 。

2) 、 TCP/IP 傳輸層使用協議端口將數據傳送給一臺主機的特定應用程序,從網絡的觀點看,協議端口是一個應用程序的進程地址。當傳輸層模塊的網絡軟件模塊要與另一個程序通信時,它將使用協議端口。Socket 是運行在傳輸層的API ,所以在使用Socket 建立連接發送數據時,要指定一個端口給它。

3) 、 根據通信性質的不同,可以把Socket 分成3 類:
① Stream socket (流套接字):該類Socket 提供雙向、有序、無重複的數據流服務,它使用於處理大量網絡數據;
② Dgram Socket (數據報套接字):該類Socket 支持雙向的數據流,但不保證數據傳輸的可靠性、有序性和無重複性,也就是說一個從Dgram Socket 接收信息的進程,有可能發現信息重複或和發出時順序不同的情況;
③ Raw Socket (原始套接字):該類 Socket 可以訪問底層的協議。

4) 、 使用Socket 接口進行網絡通信的過程如圖5-1 所示,簡要步驟如下:
① 建立一個socket ;
② 按要求配置socket ,即將socket 連接到遠程主機或給socket 指定一個本地協議端口;
③ 按要求通過socket 發送和接收數據;
④ 關閉此socket 。

2 、C# 編程要點 

根據上述的步驟,使用C# 設計通過Socket 實現點對點通信的程序需要掌握4 個編程要點:socket 的構造、socket 的配置和連接、數據的發送和接收、socket 的關閉。

1) 、命名空間的添加 
using System.Net;
using System.Net.Socket; // 用於操縱Socket 類

2) 、構造一個新的socket 對象 
在C# 中,採用socket 函數構造一個socket 對象,socket 函數原型如下:
public Socket (AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType);

AddressFamily 成員指定socket 用來解析地址的尋址方案。例如,InterNetwork 表示需要一個IP 版本4 的地址,InterNetworkV6 表示IP版本6 的地址。

SocketType 參數指定Socket 的類型。例如,Raw 支持對基礎傳輸協議的訪問,Stream 支持可靠、雙向、基於連接的數據流。

ProtocolType 指定Socket 類支持的協議。例如,IP 表示網際協議,TCP 表示傳輸控制協議。
注意 :3 個參數不是獨立的,有些地址族會限制可與其一起使用的協議,並且套接字類型在協議中通常是隱式的。如果地址族、套接字類型和協議類型不匹配將導致無效的Socket 。

例如,構造一個新的Socket 對象,採用IP 版本4 的地址,支持可靠、雙向、基於連接的數據流,採用TCP 協議:
Socket sock=new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp)

3) 、Socket 的配置和連接 
爲了將Socket 和主機關聯,必須將主機表示成網絡端點的形式。在C# 中,採用IPEndPoint 類表示網絡端點,IPEndPoint 函數原型如下:
① public IPEndPoint (IPAddress address,int port )
參數:address 表示IP 地址,port 表示提供服務的端口號。
在服務器端將構造socket 對象與表示服務器的網絡端點綁定,然後開始進行監聽,在收到連接請求後建立連接。

主要用語以下3 個函數:Bind 、Listen 和Accept 。
函數原型如下:
② public void Bind(EndPoint localEP)
參數localEP 爲與socket 關聯的網絡端點。

③ public void Listen(int backlog)
參數backlog 爲掛連接隊列的最大長度

④ public Socket Accept() 
返回值爲socket ,用於處理接收的連接請求。

例 :構造一個服務器的網絡端點,對socket 進行綁定,開始監聽,接受連接請求。

IPAddress ServerIP=IPAdress.Parse("192.18.16.186"); // 設定服務器IP 地址
IPEndPoint Server=new IPEndPoint(ServerIP,8866); // 生成服務器網絡端點
Socket Sock=new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp) // 構造一個socket
Sock.Bind(Server); // 將socket 和服務器綁定
Sock.Listen(8); // 開始監聽,允許連接隊列的長度爲8
Socket connectsock=sock.Accept(); // 返回socket ,用於同連接請求的socket 通信


客戶端向服務器端發出連接請求,用到Connect 函數,Connect 函數原型如下:
⑤ public Connect(EndPoint remoteEP)
參數:remoteEP 表示要連接的服務器端點。例如向服務器端發出連接請求,服務器IP 爲ServerIP ,端口爲Port 。
IPEndPoint Server=new IPEndPoint(ServerIP,Port); // 定義要連接的服務器端點
Sock=new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp) // 構造一個socket
Sock.Connect(Server); // 與服務器連接

4) 、數據的傳送和接收 
使用兩個用於傳送和接收數據的函數:Send 、Receive 。函數原型如下:
◆ public int Send(byte[] buffer,int size,SocketFlag socketFlags)
參數:buffer 表示要發送的數據;size 表示要發送數據的大小;socketFlags 提供Socket 消息的常數值,具有允許按位組合其成員值的屬性。
返回值爲發送到socket 的字節數。

◆ public int Receive(byte[] buffer,int size,SocketFlage socketFlags)
參數:buffer 表示接收到的數據的存儲位置;size 表示要接收數據的大小;socketFlags 提供Socket 消息的常數值,具有允許按位組合其成員值的屬性。
返回值爲接收到socket 的字節數。

例 :接收來自客戶端的數據,同時將該數據返回到客戶端。Socket 是前面例子中定義和設置好的。

public static string data=null; // 定義字符串變量存放接收到的信息
bytes=new byte[1024];
int bytesRec=connectsock.Receive(bytes,bytes.Lentgh,0); // 接受來自客戶端的數據
Console.WriteLine("Text received:{0}",bytes); // 顯示接收到的數據
connectsock.Send(bytes,bytes.Length,0); // 發送數據到客戶端

5) 、socket 的關閉 
在socket 關閉之前,要確保已經發送和接收完所有掛起的數據,因此在關閉socket 之前,要先調用Shutdown ,函數原型如下:
◆ public void Shutdown(SocketShutdown how)
參數:SocketShutdown 指定不再允許的操作。成員名稱:Both 禁止socket 發送和接收;Receive 禁止socket 接收數據;Send 禁止socket發送數據。

採用close 函數強制關閉Socket 連接。函數原型如下:
◆ public void clsoe()
當該套接字被關閉時,Connected 屬性將被設置爲false 。


發佈了138 篇原創文章 · 獲贊 32 · 訪問量 107萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章