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博客
标签:01,关闭,Socket,版本号,Win,版本,接字,函数 From: https://www.cnblogs.com/BroccoliFighter/p/17764517.html