C# Socket編程 筆記,Socket 詳解,入門簡單


目錄

一,網絡基礎

二,Socket 對象

三,Bind() 綁定與 Connect() 連接

四,Listen() 監聽請求連接 和 Accept() 接收連接請求

五,Receive() 與 Send()

六,釋放資源

七,IPAddress 和 IPEndPoint

2019-2-14 晚上第一次寫,后面會不斷修改、更新。

文章按照 Socket 的 創建、連接、傳輸數據、釋放資源的過程來寫。給出方法、參數的詳細信息。


一,網絡基礎

說到 Socket,需要學習一下TCP/IP的知識,了解一下OSI 網絡模。 

推薦別人的文章,可以很快地了解這些。

https://www.cnblogs.com/ysyn/p/3399351.html

https://www.cnblogs.com/wangcq/p/3520400.html


 二,Socket 對象

 無論是服務器還是客戶端,都要創建一個 SOCKET  對象,創建方法一致。

以下是常見的 Socket 對象創建實例

Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//監控 ip4 地址,套接字類型為 TCP ,協議類型為 TCP

其有三個構造函數

public Socket(SocketInformation socketInformation);
public Socket(SocketType socketType, ProtocolType protocolType);
public Socket(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType);

第一個構造函數,SocketInformation 對象保存的是

Socket(SocketType, ProtocolType)

實質上跟第二個構造函數是一樣的。就好像你可以直接把( 一個蘋果 , 一個梨)直接放進籃子,也可以先給 水果包裝好 再放進籃子里。

下面將解釋所有參數的意義。

 SocketType

 指定 Socket 類的實例表示的套接字類型。

TCP 用主機的IP地址加上主機上的端口號作為 TCP 連接的端點,這種端點就叫做套接字(socket)或插口。 套接字用(IP地址:端口號)表示。

 SocketType enum 類型,其字段如下

  

SocketType

  值 

對應的ProtocolType

描述

Unknown

-1

  Unknown              

指定未知的 Socket 類型。

Stream(使用字節流)

1

Tcp

支持可靠、雙向、基於連接的字節流

Dgram(使用數據報)

2

Udp

面向無連接

Raw

3

Icmp、lgmp

支持對基礎傳輸協議的訪問

Rdm

4

 

支持無連接、面向消息、以可靠方式發送的消息,

並保留數據中的消息邊界

Seqpacket

5

 

在網絡上提供排序字節流的面向連接且可靠的雙向傳輸

如需了解更詳細的資料,請查閱Microsoft文檔

地址: https://docs.microsoft.com/zh-cn/dotnet/api/system.net.sockets.sockettype?view=netframework-4.7.2

ProtocolType

表示協議類型,是一個 enum 類型。

其所有字段如下

協議類型

描述

Ggp 3

網關到網關協議。

Icmp 1

Internet 控制消息協議。

IcmpV6 58

IPv6 的 Internet 控制消息協議。

Idp 22

Internet 數據報協議。

Igmp 2

Internet 組管理協議。

IP 0

Internet 協議。

IPSecAuthenticationHeader 51

IPv6 身份驗證標頭。 有關詳細信息,請參閱https://www.ietf.org 上的 RFC 2292,第 2.2.1 節。

IPSecEncapsulatingSecurityPayload 50

IPv6 封裝安全負載標頭。

IPv4 4

Internet 協議版本 4。

IPv6 41

Internet 協議版本 6 (IPv6)。

IPv6DestinationOptions 60

IPv6 目標選項標頭。

IPv6FragmentHeader 44

IPv6 片段標頭。

IPv6HopByHopOptions 0

IPv6 逐跳選項標頭。

IPv6NoNextHeader 59

IPv6 無下一個標頭。

IPv6RoutingHeader 43

IPv6 路由標頭。

Ipx 1000

Internet 數據包交換協議。

ND 77

網絡磁盤協議(非正式)。

Pup 12

PARC 通用數據包協議。

Raw 255

原始 IP 數據包協議。

Spx 1256

順序包交換協議。

SpxII 1257

順序包交換版本 2 協議。

Tcp 6

傳輸控制協議。

Udp 17

用戶數據報協議。

Unknown -1

未知的協議。

Unspecified 0

未指定的協議。

AddressFamily

表示使用的網絡尋址方案,是一個 enum 類型。

地址類型

描述

AppleTalk 16

AppleTalk 地址。

Atm 22

本機 ATM 服務地址。

Banyan 21

Banyan 地址。

Ccitt 10

CCITT 協議(如 X.25)的地址。

Chaos 5

MIT CHAOS 協議的地址。

Cluster 24

Microsoft 群集產品的地址。

DataKit 9

Datakit 協議的地址。

13

直接數據鏈接接口地址。

DecNet 12

DECnet 地址。

Ecma 8

歐洲計算機制造商協會 (ECMA) 地址。

FireFox 19

FireFox 地址。

HyperChannel 15

NSC Hyperchannel 地址。

Ieee12844 25

IEEE 1284.4 工作組地址。

3

ARPANET IMP 地址。

InterNetwork 2

IP 版本 4 的地址。

InterNetworkV6 23

IP 版本 6 的地址。

Ipx 6

IPX 或 SPX 地址。

Irda 26

IrDA 地址。

Iso 7

ISO 協議的地址。

Lat 14

LAT 地址。

Max 29

MAX 地址。

NetBios 17

NetBios 地址。

NetworkDesigners 28

支持網絡設計器 OSI 網關的協議的地址。

NS 6

Xerox NS 協議的地址。

Osi 7

OSI 協議的地址。

Pup 4

PUP 協議的地址。

Sna 11

IBM SNA 地址。

Unix 1

Unix 本地到主機地址。

Unknown -1

未知的地址族。

Unspecified 0

未指定的地址族。

VoiceView 18

VoiceView 地址。

 

 Socket 官方文檔地址

https://docs.microsoft.com/zh-cn/dotnet/api/system.net.sockets.socket?redirectedfrom=MSDN&view=netframework-4.7.2


三,Bind() 綁定與 Connect() 連接

Bind() 用於綁定 IPEndPoint 對象,在服務端使用。

Connect() 在客戶端使用,用於連接服務端。

創建 Socket 對象后,接着 綁定本地Socket / 連接服務端

Bind()

public void Bind (System.Net.EndPoint localEP);

使用方法

        Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        IPAddress iP = IPAddress.Parse("127.0.0.1");

        //上面不重要,看下面

    //IPEndPoint iPEndPoint = new IPEndPoint(iP, 2300);
    //serverSocket.Bind(iPEndPoint);

       serverSocket.Bind(new IPEndPoint(iP, 2300))

 你將在在本地創建 IPEndPoint 對象,擁有此 ip:post 的訪問權限。目的是綁定本地機器的某個端口,所有經過此端口的數據就歸你管了。

 

Connect()

 與遠程主機建立連接。Connect() 有四個重載方法,不必關注,只需知道,必需提供 IP 和 Post 兩個值。

使用方法

            IPAddress iP = IPAddress.Parse("127.0.0.1");
            IPEndPoint iPEndPoint = new IPEndPoint(iP, 2300);
            Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

        //創建與遠程主機的連接 serverSocket.Connect(iPEndPoint);

四,Listen() 監聽請求連接 和 Accept() 接收連接請求

Listen()

監控所有發送到此主機的、特點端口的連接請求。服務端使用,客戶端不需要。

public void Listen (int backlog);

使用 Bind() 后,使用 Listen() 方法進行監控,backlog 參數指定可排隊等待接受的傳入連接的數量,即掛起的連接隊列的最大長度

 示例

serverSocket.Listen(10);    //開始監聽

Accept()

Accept() 以同步方式監聽套接字,在連接請求隊列中提取第一個掛起的連接請求,然后創建並返回一個新的 Socket 對象。

代碼示例

            //創建終結點(EndPoint)
            IPAddress ip = IPAddress.Any;             
            IPEndPoint ipe = new IPEndPoint(ip, 8000);

            //創建 socket 並開始監聽
            Socket serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            serverSocket.Bind(ipe);
            serverSocket.Listen(10);//開始監聽

            //接受到client連接,為此連接建立新的socket,並接受信息
            Socket temp = serverSocket.Accept();//為新建連接創建新的socket
//關閉連接
temp.Close(); 

 

注意的是,每次建立連接是一個 Accept() 對象,如果你要進行 服務器-客戶端互相通訊,應使用同一個 Accept() 對象。每個 Accept 對象都是 從客戶端請求建立開始的,期間只要使用同一個 Accept 對象,都可以進行數據傳輸。


 五,Receive() 與 Send()

  • Receive() 接收信息
  • Send() 發送信息

在服務端和客戶端都使用這兩個方法。

Receive()

使用示例

            string recvStr = "";
            byte[] recvBytes = new byte[1024];
            int bytes;
            bytes = temp.Receive(recvBytes, recvBytes.Length, 0);//從客戶端接受信息
            recvStr += Encoding.ASCII.GetString(recvBytes, 0, bytes);

 

直接從微軟那復制來的。

Receive(Byte[], Int32, Int32, SocketFlags, SocketError)

使用指定的 Socket,從綁定的 SocketFlags 接收數據,將數據存入接收緩沖區。

Receive(Byte[], Int32, Int32, SocketFlags)

使用指定的 Socket,從綁定的 SocketFlags 接收指定的字節數,存入接收緩沖區的指定偏移量位置。

Receive(IList<ArraySegment<Byte>>, SocketFlags, SocketError)

使用指定的 Socket,從綁定的 SocketFlags 接收數據,將數據存入接收緩沖區列表中。

Receive(Byte[], Int32, SocketFlags)

使用指定的 Socket,從綁定的 SocketFlags 接收指定字節數的數據,並將數據存入接收緩沖區。

Receive(Byte[], SocketFlags)

使用指定的 Socket,從綁定的 SocketFlags 接收數據,將數據存入接收緩沖區。

Receive(IList<ArraySegment<Byte>>, SocketFlags)

使用指定的 Socket,從綁定的 SocketFlags 接收數據,將數據存入接收緩沖區列表中。

Receive(IList<ArraySegment<Byte>>)

從綁定的 Socket 接收數據,將數據存入接收緩沖區列表中。

Receive(Byte[])

從綁定的 Socket 套接字接收數據,將數據存入接收緩沖區。

參數

Byte[] buffer 

Byte 類型的數組,它是存儲接收到的數據的位置。

Int32 offset 

buffer 參數中的位置,用於存儲所接收的數據。

Int32 size

要接收的字節數。

SocketFlags socketFlags

SocketFlags 值的按位組合。

SocketError errorCode

一個 SocketError 對象,它存儲套接字錯誤。

socketFlags 默認值為 0 None ,筆者沒有搞懂 socketFlags 的應用場景。

返回

返回已成功讀取的字節數。

Send()

send()跟Receive()用法相似,

 示例代碼如下

            string str = "hello";
            byte[] a = Encoding.UTF8.GetBytes(str);
            send = socket.Send(a, 0);

 

發送/接收 都是使用 byte[] 字節流,所以接收時要進行轉換。


六,釋放資源

Accept 釋放和 Socket 的釋放。

Accept 是連接對象,一個 Socket 可能有數十個 Accept 連接。

使用 Shutdown( ) 方法可以 禁止 Asscpt 對象的操作(禁用某個 Socket 對象 的發送和接收)。

public void Shutdown (System.Net.Sockets.SocketShutdown how);

SocketShutdown 是一個 enum 類型。

實例

            temp.Shutdown(SocketShutdown.Receive);
            //禁止接收 
使用 描述
發送 Send 禁止對此發送Socket
接收 Receive 禁用對此接收Socket
消息和傳送 Both 禁用發送和接收對此Socket

close()

會直接釋放資源,AcceptSocket 對象都可以使用。使用后對象將徹底釋放。


七,IPAddress 和 IPEndPoint

//引入
using
System.Net;

IPAddress 用來處理IP地址、轉換IP地址

IPAddress.Parse() 方法可以把以小數點隔分的十進制 IP 表示轉化成 IPAddress 類。

IPAddress ip = IPAddress.Parse("127.0.0.1");//把ip地址字符串轉換為IPAddress類型的實例

IPAddress提供4個只讀字段

  • Any 用於代表本地系統可用的任何IP地址
  • Broadcase用於代表本地網絡的IP廣播地址
  • Loopback用於代表系統的回送地址
  • None用於代表系統上沒有網絡接口

關於其類型的使用和全部方法、構造函數等,請查看文檔Microsoft文檔。

地址 https://docs.microsoft.com/zh-cn/dotnet/api/system.net.ipaddress?view=netframework-4.7.2

IPEndPoint 表示IPAddress對象與端口的綁定

            IPAddress ip = IPAddress.Any;              //把ip地址字符串轉換為IPAddress類型的實例
            IPEndPoint ipe = new IPEndPoint(ip, 8000);//用指定的端口和ip初始化IPEndPoint類的新實例

上面的代碼,創建一個監控點,端口是 8000,對象是 本地所有IP

另外,此類能夠獲取查看端口的值范圍,除此外,此類沒有太大意義。

Microsoft 文檔地址 https://docs.microsoft.com/zh-cn/dotnet/api/system.net.ipendpoint?view=netframework-4.7.2

 

SocketType


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM