C#之Socket(套接字)通信

一、socket是什麼

Socket是應用層與TCP/IP協議族通信的中間軟件抽象層,它是一組接口。在設計模式中,Socket其實就是一個門面模式,它把復雜的TCP/IP協議族隱藏在Socket接口後面,對用戶來說,一組簡單的接口就是全部,讓Socket去組織數據,以符合指定的協議。所以,我們無需深入理解tcp/udp協議,socket已經為我們封裝好瞭,我們隻需要遵循socket的規定去編程,寫出的程序自然就是遵循tcp/udp標準的。

二、套接字的工作流程

先從服務器端說起。服務器端先初始化Socket,然後與端口綁定(bind),對端口進行監聽(listen),調用accept阻塞,等待客戶端連接。在這時如果有個客戶端初始化一個Socket,然後連接服務器(connect),如果連接成功,這時客戶端與服務器端的連接就建立瞭。客戶端發送數據請求,服務器端接收請求並處理請求,然後把回應數據發送給客戶端,客戶端讀取數據,最後關閉連接,一次交互結束。

三、服務端

private void btnListen_Click(object sender, EventArgs e)
{
    IPEndPoint point = new IPEndPoint(IPAddress.Any, 13000);//IPAddress.Any本機任何網卡IP。本機端口查看netstat -an
    //服務端Socket定義
    Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    socket.Bind(point); //綁定IP
    socket.Listen(10);//啟動監聽。最大監聽數,同一個時間點過來10個客戶端,排隊
    ShowMsg("服務器開始監聽");

    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)
    {
        //接收客戶端發送過來的數據
        try
        {
            //定義byte數組存放從客戶端接收過來的數據
            byte[] buffer = new byte[1024 * 1024];
            
           int n = clientSocket.Receive(buffer);//將接收過來的數據放到buffer中,並返回實際接受數據的長度

            //將字節轉換成字符串
            string words = Encoding.Unicode.GetString(buffer, 0, n);
            Console.WriteLine(clientSocket.RemoteEndPoint.ToString() + ":" + words);
            byte[] msg = Encoding.Unicode.GetBytes(words);
            clientSocket.Send(msg);//發送數據,字節數組
        }
        catch (Exception ex)
        {
            break;
        }
    }
    clientSocket.Shutdown(SocketShutdown.Both);//禁止發送和接受數據
    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);//連接成功後,就可以接收服務器發送的信息瞭
th.IsBackground = true;
th.Start();

clientSocket.Shutdown(SocketShutdown.Both);//禁止發送和接受數據
clientSocket.Close();//關閉socket,釋放資源

五、Socket對象的成員

1、屬性

名稱 說明
AddressFamily 獲取 Socket 的地址族。
Available 獲取已經從網絡接收且可供讀取的數據量。
Blocking 獲取或設置一個值,該值指示 Socket 是否處於阻止模式。
Connected 獲取一個值,該值指示 Socket 是在上次 Send 還是 Receive 操作時連接到遠程主機。
Handle 獲取 Socket 的操作系統句柄。
LocalEndPoint 獲取本地終結點。
RemoteEndPoint 獲取遠程終結點。
ProtocolType 獲取 Socket 的協議類型。
SocketType 獲取 Socket 的類型。
ReceiveBufferSize 獲取或設置一個值,它指定 Socket 接收緩沖區的大小。
ReceiveTimeout 獲取或設置一個值,該值指定之後同步 Receive 調用將超時的時間長度。
SendBufferSize 獲取或設置一個值,該值指定 Socket 發送緩沖區的大小。
SendTimeout 獲取或設置一個值,該值指定之後同步 Send 調用將超時的時間長度。

2、方法

Accept

名稱 說明
Accept() 為新建連接創建新的 Socket。
BeginAccept(AsyncCallback, Object)   開始一個異步操作來接受一個傳入的連接嘗試。
EndAccept(Byte[], IAsyncResult) 異步接受傳入的連接嘗試,並創建新的 Socket 對象來處理遠程主機通信。 此方法返回包含所傳輸的初始數據的緩沖區。
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 套接字接收數據,將數據存入接收緩沖區。
BeginReceive(Byte[], Int32, Int32, SocketFlags, AsyncCallback, Object) 開始從連接的 Socket 中異步接收數據。
EndReceive(IAsyncResult) 結束掛起的異步讀取。
ReceiveAsync(SocketAsyncEventArgs) 開始一個異步請求以便從連接的 Socket 對象中接收數據。

ReceiveFrom

名稱 說明
ReceiveFrom(Byte[], EndPoint) 將數據報接收到數據緩沖區並存儲終結點。
BeginReceiveFrom(Byte[], Int32, Int32, SocketFlags, EndPoint, AsyncCallback, Object) 開始從指定網絡設備中異步接收數據。
EndReceiveFrom(IAsyncResult, EndPoint) 結束掛起的、從特定終結點進行異步讀取。
ReceiveFromAsync(SocketAsyncEventArgs) 開始從指定網絡設備中異步接收數據。

ReceiveMessageFrom

名稱 說明
ReceiveMessageFrom(Byte[], Int32, Int32, SocketFlags, EndPoint, IPPacketInformation) 使用指定的 SocketFlags 將指定字節數的數據接收到指定的數據緩沖區位置,並存儲終結點和數據包信息。
BeginReceiveMessageFrom(Byte[], Int32, Int32, SocketFlags, EndPoint, AsyncCallback, Object) 開始使用指定的 SocketFlags 將指定字節數的數據異步接收到數據緩沖區的指定位置,然後存儲終結點和數據包信息。
EndReceiveMessageFrom(IAsyncResult, SocketFlags, EndPoint, IPPacketInformation) 結束掛起的、從特定終結點進行異步讀取。 此方法還顯示有關數據包而不是 EndReceiveFrom(IAsyncResult, EndPoint) 的更多信息。
ReceiveMessageFromAsync(SocketAsyncEventArgs) 開始使用指定的 SocketFlags 將指定字節數的數據異步接收到數據緩沖區的指定位置,並存儲終結點和數據包信息。

Send

名稱 說明
Send(Byte[]) 將數據發送到連接的 Socket。
BeginSend(Byte[], Int32, Int32, SocketFlags, AsyncCallback, Object) 將數據異步發送到連接的 Socket。
EndSend(IAsyncResult) 結束掛起的異步發送。
SendAsync(SocketAsyncEventArgs) 將數據異步發送到連接的 Socket 對象。

SendFile

名稱 說明
SendFile(String) 使用 Socket 傳輸標志,將文件 fileName 發送到連接的 UseDefaultWorkerThread 對象。
BeginSendFile(String, AsyncCallback, Object) 使用 Socket 標志,將文件 fileName 發送到連接的 UseDefaultWorkerThread 對象。
EndSendFile(IAsyncResult) 結束文件的掛起異步發送。

SendTo

名稱 說明
SendTo(Byte[], EndPoint) 將數據發送到指定的終結點。
BeginSendTo(Byte[], Int32, Int32, SocketFlags, EndPoint, AsyncCallback, Object) 以異步方式將數據發送到特定遠程主機。
EndSendTo(IAsyncResult) 結束掛起的、向指定位置進行的異步發送。
SendToAsync(SocketAsyncEventArgs) 以異步方式將數據發送到特定遠程主機。

其它

名稱 說明
Select(IList, IList, IList, Int32) 確定一個或多個套接字的狀態。
SendPacketsAsync(SocketAsyncEventArgs) 將文件集合或者內存中的數據緩沖區以異步方法發送給連接的 Socket 對象。
Bind(EndPoint) 使 Socket 與一個本地終結點相關聯。
Listen(Int32) 將 Socket 置於偵聽狀態。
CancelConnectAsync(SocketAsyncEventArgs) 取消一個對遠程主機連接的異步請求。
GetSocketOption(SocketOptionLevel, SocketOptionName) 返回指定的 Socket 選項的值,表示為一個對象。
SetSocketOption(SocketOptionLevel, SocketOptionName, Boolean) 將指定的 Socket 選項設置為指定的 Boolean 值。
SetIPProtectionLevel(IPProtectionLevel) 設置套接字的 IP 保護級別。
Shutdown(SocketShutdown) 禁用某 Socket 上的發送和接收。
Close() 關閉 Socket 連接並釋放所有關聯的資源。
Dispose() 釋放 Socket 類的當前實例所使用的所有資源。

到此這篇關於C#之Socket(套接字)通信的文章就介紹到這瞭。希望對大傢的學習有所幫助,也希望大傢多多支持WalkonNet。

推薦閱讀: