01啟動(關閉)套接字

西蘭花戰士發表於2023-10-14

windows作業系統為我們提供了一套底層Socket API,用於實現網路通訊。在我們編寫的程式中,如果需要引用該網路庫,需要實現以下幾步:

1、包含標頭檔案

1 #include <WinSock2.h>

其中,標頭檔案<WinSock2.h>表示Windows Socket 第二版,第一版為 <winsock.h>。

2、引入庫檔案

1 #pragma comment(lib,"ws2_32.lib")

上邊程式碼是將ws2_32.lib庫檔案引入到工程,該庫中包含了<WinSock2.h>標頭檔案中的實現部分。需要注意的是,不管是32位編譯環境還是64位編譯環境,都是使用該庫檔案。如果需要使用第一版的網路庫,可以引入"wsock32.lib"。

3、開啟網路庫

在使用Socket套接字之前,需要呼叫WSAStartup函式啟動Win Socket套接字服務,該函式定義如下:

int WSAStartup(
    WORD        wVersionRequired,
    LPWSADATA    lpWSAData
);

引數

  • wVersionRequired:用於指定Win Socket套接字版本。其中,低位元組代表主版本,高位元組代表次版本。
  • lpWSAData:輸出型引數,指向WSADATA型別的指標,該指標中儲存Win Socket套接字實現的詳細資訊。

返回值

如果該函式執行成功,WSAStartup函式返回0。否則,它將返回如下錯誤程式碼:

錯誤程式碼 含義
WSASYSNOTREADY 10091  底層網路子系統尚未準備好進行網路通訊。
WSAVERNOTSUPPORTED 10092 不支援給定的版本號,檢查是不是將主版本號設定為0。
WSAEINPROGRESS 10036 當一個阻塞函式正在進行時,呼叫任何Windows Sockets API函式均返回此錯誤。
WSAEPROCLIM 10067 Windows Sockets實現可能限制同時使用它的應用程式的數量,如果達到此限制,則返回該錯誤。
WSAEFAULT 10014 lpWSAData指標錯誤,檢查是否傳入nullptr。

 

 

 

 

 

版本號

Win Socket當前支援的最大版本號為2.2版,當前支援的所有版本為:1.0、1.1、2.0、2.1、2.2。

可以透過 MAKEWORD 宏構造一個版本號,例如:

//MAKEWORD(lowbyte, highbyte)
WORD wdVersion = MAKEWORD(2, 1);      //構造2.1版本

當輸入不存在的版本號時,有以下幾種情況:

  • 有主版本號,沒副版本號:編譯返回該主版本號的最大副版本號。例如:輸入2.3,則使用2.2版本。
  • 超過最大版本號或者主版本號為負數:則返回系統能提供的最大版本號。例如,輸入3.3,返回2.2版本。
  • 主版本號是0:網路庫開啟失敗,返回WSAVERNOTSUPPORTED錯誤碼,不支援的套接字版本。

WSAData結構體

該結構儲存了Win Socket套接字實現的詳細資訊。該結構體定義如下:

1 struct WSAData {
2   WORD           wVersion;          //當前使用的版本。
3   WORD           wHighVersion;      //當前支援的最高版本。
4   unsigned short iMaxSockets;       //[2版本棄用]返回當前可用的Socket數量
5   unsigned short iMaxUdpDg;         //[2版本棄用]UDP資料包資訊大小
6   char           *lpVendorInfo;     //[2版本棄用]供應商特定資訊
7   char           szDescription[WSADESCRIPTION_LEN + 1];    //以NULL結尾的ASCII字串,描述Win Socket套接字實現說明。
8   char           szSystemStatus[WSASYS_STATUS_LEN + 1];    //以NULL結尾的ASCII字串,描述相關狀態或配置資訊。
9 };

4、關閉網路庫

當Win Socket套接字執行完畢後,需要呼叫WSACleanup函式關閉套接字,釋放分配的資源,該函式定義如下:

1 int WSACleanup();

返回值

如果該函式執行成功,則返回值為0,否則,返回下列錯誤程式碼:

錯誤程式碼 含義
WSANOTINITIALISED 10093 在使用該函式之前,必須成功呼叫WSAStartup
WSAENETDOWN 10050 套接字操作遇到一個不活動的網路。此錯誤可能指示網路系統(例如WinSock DLL執行的協議棧)、網路介面或本地網路本身發生了一個嚴重的失敗。
WSAEINPROGRESS 10036 一個阻塞操作正在執行。Windows Sockets只允許一個任務(或執行緒)在同一時間可以有一個未完成的阻塞操作,如果此時呼叫了任何函式,將返回該錯誤。

 

 

 

 

 

 

示例程式

 1 #include <iostream>
 2 #include <WinSock2.h>
 3 #pragma comment(lib,"ws2_32.lib")
 4 using namespace std;
 5 
 6 const unsigned short MajorVersion = 2;        //主版本號
 7 const unsigned short MinorVersion = 2;        //副版本號
 8 
 9 int main()
10 {
11     WORD wdVersion = MAKEWORD(MajorVersion, MinorVersion);
12     WSAData wSocketInfo;
13     int nRet = WSAStartup(wdVersion, &wSocketInfo);
14     if (nRet != 0)
15     {
16         std::cout << "open error!" << std::endl;
17         return;
18     }
19 
20     //版本檢驗
21     if (MinorVersion != HIBYTE(wSocketInfo.wVersion) ||
22         MajorVersion != LOBYTE(wSocketInfo.wVersion))
23     {
24         assert(0);
25         WSACleanup();
26         return 0;
27     }
28     ...
29     
30     WSACleanup();
31 }

 

參考

Windows Sockets 錯誤碼及出錯原因-chenshko-ChinaUnix部落格

 

相關文章