C#之Socket(套接字)通信
一、socket是什么
Socket是應用層與TCP/IP協(xié)議族通信的中間軟件抽象層,它是一組接口。在設計模式中,Socket其實就是一個門面模式,它把復雜的TCP/IP協(xié)議族隱藏在Socket接口后面,對用戶來說,一組簡單的接口就是全部,讓Socket去組織數(shù)據(jù),以符合指定的協(xié)議。所以,我們無需深入理解tcp/udp協(xié)議,socket已經(jīng)為我們封裝好了,我們只需要遵循socket的規(guī)定去編程,寫出的程序自然就是遵循tcp/udp標準的。
二、套接字的工作流程

先從服務器端說起。服務器端先初始化Socket,然后與端口綁定(bind),對端口進行監(jiān)聽(listen),調(diào)用accept阻塞,等待客戶端連接。在這時如果有個客戶端初始化一個Socket,然后連接服務器(connect),如果連接成功,這時客戶端與服務器端的連接就建立了??蛻舳税l(fā)送數(shù)據(jù)請求,服務器端接收請求并處理請求,然后把回應數(shù)據(jù)發(fā)送給客戶端,客戶端讀取數(shù)據(jù),最后關閉連接,一次交互結束。
三、服務端
private void btnListen_Click(object sender, EventArgs e)
{
IPEndPoint point = new IPEndPoint(IPAddress.Any, 13000);//IPAddress.Any本機任何網(wǎng)卡IP。本機端口查看netstat -an
//服務端Socket定義
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
socket.Bind(point); //綁定IP
socket.Listen(10);//啟動監(jiān)聽。最大監(jiān)聽數(shù),同一個時間點過來10個客戶端,排隊
ShowMsg("服務器開始監(jiān)聽");
Thread thread = new Thread(AcceptInfo);
thread.Start(socket);
}
//記錄通信用的Socket
Dictionary<string, Socket> dic = new Dictionary<string, Socket>();
// private Socket client;
void AcceptInfo(object o)
{
Socket socket = o as Socket;
while (true)
{
//通信用socket
try
{
Socket clientSocket = socket.Accept();//如果客戶端有請求,生成一個新的Socket
string point = clientSocket.RemoteEndPoint.ToString();
ShowMsg(point + "連接客戶端成功!");
dic.Add(point, clientSocket);
//接收消息
Thread th = new Thread(ReceiveMsg);
th.Start(clientSocket);
}
catch (Exception ex)
{
break;
}
}
socket.Close();
}
//接收消息
void ReceiveMsg(object socket)
{
Socket clientSocket = socket as Socket;
while (true)
{
//接收客戶端發(fā)送過來的數(shù)據(jù)
try
{
//定義byte數(shù)組存放從客戶端接收過來的數(shù)據(jù)
byte[] buffer = new byte[1024 * 1024];
int n = clientSocket.Receive(buffer);//將接收過來的數(shù)據(jù)放到buffer中,并返回實際接受數(shù)據(jù)的長度
//將字節(jié)轉換成字符串
string words = Encoding.Unicode.GetString(buffer, 0, n);
Console.WriteLine(clientSocket.RemoteEndPoint.ToString() + ":" + words);
byte[] msg = Encoding.Unicode.GetBytes(words);
clientSocket.Send(msg);//發(fā)送數(shù)據(jù),字節(jié)數(shù)組
}
catch (Exception ex)
{
break;
}
}
clientSocket.Shutdown(SocketShutdown.Both);//禁止發(fā)送和接受數(shù)據(jù)
clientSocket.Close();//關閉socket,釋放資源
}四、客戶端
Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
IPEndPoint point = new IPEndPoint("127.0.0.1", 13000));//連接到的服務端IP
clientSocket.Connect(point);//連接到服務器
ShowMsg("連接成功");
ShowMsg("服務器" + client.RemoteEndPoint.ToString());
ShowMsg("客戶端:" + client.LocalEndPoint.ToString());
Thread th = new Thread(ReceiveMsg);//連接成功后,就可以接收服務器發(fā)送的信息了
th.IsBackground = true;
th.Start();
clientSocket.Shutdown(SocketShutdown.Both);//禁止發(fā)送和接受數(shù)據(jù)
clientSocket.Close();//關閉socket,釋放資源五、Socket對象的成員
1、屬性
| 名稱 | 說明 |
|---|---|
| AddressFamily | 獲取 Socket 的地址族。 |
| Available | 獲取已經(jīng)從網(wǎng)絡接收且可供讀取的數(shù)據(jù)量。 |
| Blocking | 獲取或設置一個值,該值指示 Socket 是否處于阻止模式。 |
| Connected | 獲取一個值,該值指示 Socket 是在上次 Send 還是 Receive 操作時連接到遠程主機。 |
| Handle | 獲取 Socket 的操作系統(tǒng)句柄。 |
| LocalEndPoint | 獲取本地終結點。 |
| RemoteEndPoint | 獲取遠程終結點。 |
| ProtocolType | 獲取 Socket 的協(xié)議類型。 |
| SocketType | 獲取 Socket 的類型。 |
| ReceiveBufferSize | 獲取或設置一個值,它指定 Socket 接收緩沖區(qū)的大小。 |
| ReceiveTimeout | 獲取或設置一個值,該值指定之后同步 Receive 調(diào)用將超時的時間長度。 |
| SendBufferSize | 獲取或設置一個值,該值指定 Socket 發(fā)送緩沖區(qū)的大小。 |
| SendTimeout | 獲取或設置一個值,該值指定之后同步 Send 調(diào)用將超時的時間長度。 |
2、方法
Accept
| 名稱 | 說明 |
|---|---|
| Accept() | 為新建連接創(chuàng)建新的 Socket。 |
| BeginAccept(AsyncCallback, Object) | 開始一個異步操作來接受一個傳入的連接嘗試。 |
| EndAccept(Byte[], IAsyncResult) | 異步接受傳入的連接嘗試,并創(chuàng)建新的 Socket 對象來處理遠程主機通信。 此方法返回包含所傳輸?shù)某跏紨?shù)據(jù)的緩沖區(qū)。 |
| AcceptAsync(SocketAsyncEventArgs) | 開始一個異步操作來接受一個傳入的連接嘗試。 |
Connect
| 名稱 | 說明 |
|---|---|
| Connect(EndPoint) | 與遠程主機建立連接。 |
| BeginConnect(EndPoint, AsyncCallback, Object) | 開始一個對遠程主機連接的異步請求。 |
| EndConnect(IAsyncResult) | 結束掛起的異步連接請求。 |
| ConnectAsync(SocketAsyncEventArgs) | 開始一個對遠程主機連接的異步請求。 |
Disconnect
| 名稱 | 說明 |
|---|---|
| Disconnect(Boolean) | 關閉套接字連接并允許重用套接字。 |
| BeginDisconnect(Boolean, AsyncCallback, Object) | 開始異步請求從遠程終結點斷開連接。 |
| EndDisconnect(IAsyncResult) | 結束掛起的異步斷開連接請求。 |
| DisconnectAsync(SocketAsyncEventArgs) | 關閉套接字連接并允許重用套接字。 |
Receive
| 名稱 | 說明 |
|---|---|
| Receive(Byte[]) | 從綁定的 Socket 套接字接收數(shù)據(jù),將數(shù)據(jù)存入接收緩沖區(qū)。 |
| BeginReceive(Byte[], Int32, Int32, SocketFlags, AsyncCallback, Object) | 開始從連接的 Socket 中異步接收數(shù)據(jù)。 |
| EndReceive(IAsyncResult) | 結束掛起的異步讀取。 |
| ReceiveAsync(SocketAsyncEventArgs) | 開始一個異步請求以便從連接的 Socket 對象中接收數(shù)據(jù)。 |
ReceiveFrom
| 名稱 | 說明 |
|---|---|
| ReceiveFrom(Byte[], EndPoint) | 將數(shù)據(jù)報接收到數(shù)據(jù)緩沖區(qū)并存儲終結點。 |
| BeginReceiveFrom(Byte[], Int32, Int32, SocketFlags, EndPoint, AsyncCallback, Object) | 開始從指定網(wǎng)絡設備中異步接收數(shù)據(jù)。 |
| EndReceiveFrom(IAsyncResult, EndPoint) | 結束掛起的、從特定終結點進行異步讀取。 |
| ReceiveFromAsync(SocketAsyncEventArgs) | 開始從指定網(wǎng)絡設備中異步接收數(shù)據(jù)。 |
ReceiveMessageFrom
| 名稱 | 說明 |
|---|---|
| ReceiveMessageFrom(Byte[], Int32, Int32, SocketFlags, EndPoint, IPPacketInformation) | 使用指定的 SocketFlags 將指定字節(jié)數(shù)的數(shù)據(jù)接收到指定的數(shù)據(jù)緩沖區(qū)位置,并存儲終結點和數(shù)據(jù)包信息。 |
| BeginReceiveMessageFrom(Byte[], Int32, Int32, SocketFlags, EndPoint, AsyncCallback, Object) | 開始使用指定的 SocketFlags 將指定字節(jié)數(shù)的數(shù)據(jù)異步接收到數(shù)據(jù)緩沖區(qū)的指定位置,然后存儲終結點和數(shù)據(jù)包信息。 |
| EndReceiveMessageFrom(IAsyncResult, SocketFlags, EndPoint, IPPacketInformation) | 結束掛起的、從特定終結點進行異步讀取。 此方法還顯示有關數(shù)據(jù)包而不是 EndReceiveFrom(IAsyncResult, EndPoint) 的更多信息。 |
| ReceiveMessageFromAsync(SocketAsyncEventArgs) | 開始使用指定的 SocketFlags 將指定字節(jié)數(shù)的數(shù)據(jù)異步接收到數(shù)據(jù)緩沖區(qū)的指定位置,并存儲終結點和數(shù)據(jù)包信息。 |
Send
| 名稱 | 說明 |
|---|---|
| Send(Byte[]) | 將數(shù)據(jù)發(fā)送到連接的 Socket。 |
| BeginSend(Byte[], Int32, Int32, SocketFlags, AsyncCallback, Object) | 將數(shù)據(jù)異步發(fā)送到連接的 Socket。 |
| EndSend(IAsyncResult) | 結束掛起的異步發(fā)送。 |
| SendAsync(SocketAsyncEventArgs) | 將數(shù)據(jù)異步發(fā)送到連接的 Socket 對象。 |
SendFile
| 名稱 | 說明 |
|---|---|
| SendFile(String) | 使用 Socket 傳輸標志,將文件 fileName 發(fā)送到連接的 UseDefaultWorkerThread 對象。 |
| BeginSendFile(String, AsyncCallback, Object) | 使用 Socket 標志,將文件 fileName 發(fā)送到連接的 UseDefaultWorkerThread 對象。 |
| EndSendFile(IAsyncResult) | 結束文件的掛起異步發(fā)送。 |
SendTo
| 名稱 | 說明 |
|---|---|
| SendTo(Byte[], EndPoint) | 將數(shù)據(jù)發(fā)送到指定的終結點。 |
| BeginSendTo(Byte[], Int32, Int32, SocketFlags, EndPoint, AsyncCallback, Object) | 以異步方式將數(shù)據(jù)發(fā)送到特定遠程主機。 |
| EndSendTo(IAsyncResult) | 結束掛起的、向指定位置進行的異步發(fā)送。 |
| SendToAsync(SocketAsyncEventArgs) | 以異步方式將數(shù)據(jù)發(fā)送到特定遠程主機。 |
其它
| 名稱 | 說明 |
|---|---|
| Select(IList, IList, IList, Int32) | 確定一個或多個套接字的狀態(tài)。 |
| SendPacketsAsync(SocketAsyncEventArgs) | 將文件集合或者內(nèi)存中的數(shù)據(jù)緩沖區(qū)以異步方法發(fā)送給連接的 Socket 對象。 |
| Bind(EndPoint) | 使 Socket 與一個本地終結點相關聯(lián)。 |
| Listen(Int32) | 將 Socket 置于偵聽狀態(tài)。 |
| CancelConnectAsync(SocketAsyncEventArgs) | 取消一個對遠程主機連接的異步請求。 |
| GetSocketOption(SocketOptionLevel, SocketOptionName) | 返回指定的 Socket 選項的值,表示為一個對象。 |
| SetSocketOption(SocketOptionLevel, SocketOptionName, Boolean) | 將指定的 Socket 選項設置為指定的 Boolean 值。 |
| SetIPProtectionLevel(IPProtectionLevel) | 設置套接字的 IP 保護級別。 |
| Shutdown(SocketShutdown) | 禁用某 Socket 上的發(fā)送和接收。 |
| Close() | 關閉 Socket 連接并釋放所有關聯(lián)的資源。 |
| Dispose() | 釋放 Socket 類的當前實例所使用的所有資源。 |
到此這篇關于C#之Socket(套接字)通信的文章就介紹到這了。希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
C#調(diào)用barTender打印標簽示例的實現(xiàn)
Bartender是最優(yōu)秀的條碼打印軟件,在企業(yè)里使用非常普遍,本文主要介紹了C#調(diào)用barTender打印標簽示例的實現(xiàn),具有一定的參考價值,感興趣的可以了解一下2023-08-08
C#實現(xiàn)通過winmm.dll控制聲音播放的方法
這篇文章主要介紹了C#實現(xiàn)通過winmm.dll控制聲音播放的方法,很實用的功能,需要的朋友可以參考下2014-08-08
C#中string和StingBuilder內(nèi)存中的區(qū)別實例分析
這篇文章主要介紹了C#中string和StingBuilder內(nèi)存中的區(qū)別,以實例形式演示了二者在內(nèi)存中的不同之處,需要的朋友可以參考下2014-09-09
詳解C# WebApi 接口測試工具:WebApiTestClient
這篇文章主要介紹了詳解C# WebApi 接口測試工具:WebApiTestClient,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-07-07

