windows socket有两个大版本,第一版头文件及对应的链接库为
#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib")
第二版本对应的链接库为
#include <WinSock2.h>
#pragma comment(lib, "wsock32.lib")
使用流程:
1、初始化动态链接库wsastartup
1.1. 名称解析
w-----windows
s----socket
a-----asynchronous 异步
startup-----启动
同步/异步/阻塞/非阻塞区别
同步异步关注的是消息的通信机制
阻塞非阻塞强调的是程序等待调用结果时的状态
同步:发出请求时,没有得到结果,该调用就不返回,一旦返回,就一定得到返回值 异步:发出请求后,调用直接返回,没有返回结果
阻塞:调用结果返回之前,当前线程挂起,只有得到结果后,才会返回
非阻塞:调用不会阻塞当前线程,相对于阻塞而言,非阻塞线程仍处于激活状态,只是逻辑上没有返回
1.2、函数参数
int WSAAPI WSAStartup(
WORD wVersionRequested, //用于协商winsock dll的最高版本
LPWSADATA lpWSAData //指向WSADATA数据结构的指针,该结构用于接收Windows套接字实现的详细信息
);
LPWSADATA数据结构:
WORD wVersion; //版本号
WORD wHighVersion //系统提供的最高版本号;
#ifdef _WIN64
unsigned short iMaxSockets; //可用socket数量,2.0以后被遗弃
unsigned short iMaxUdpDg;//udp数据报大小,2.0以后被遗弃
char FAR * lpVendorInfo;//2.0以后被遗弃
char szDescription[WSADESCRIPTION_LEN+1];
char szSystemStatus[WSASYS_STATUS_LEN+1];
#else
char szDescription[WSADESCRIPTION_LEN+1];
char szSystemStatus[WSASYS_STATUS_LEN+1];
unsigned short iMaxSockets;
unsigned short iMaxUdpDg;
char FAR * lpVendorInfo;
1.3、返回值
WSASYSNOTREADY
代码数值为10091,指出网络通信依赖的网络子系统还没有准备好。
WSAVERNOTSUPPORTED
代码数值为10092,表示所需的Windows Sockets API的版本未由特定的Windows Sockets实现提供。
WSAEINVAL
代码数值为10022,说明应用程序指出的Windows Sockets版本不被该DLL支持。
WSAEINPROGRESS
代码数值为10036,说明一个阻塞的Winsock调用正在进行中。
WSAEPROCLIM
代码数值为10067,说明已经达到了Windows Sockets实现所支持的任务数量的极限。
WSAEFAULT
代码数值为10014,说明lpWSADATA参数是一个无效的指针。
1.4、版本校验
LOWORD()得到一个32bit数的低16bit HIWORD()得到一个32bit数的高16bit
LOBYTE()得到一个16bit数最低(最右边)那个字节 HIBYTE()得到一个16bit数最高(最左边)那个字节
1.5、关闭网络库
调用WSACleanup()解除与Socket库的绑定并且释放Socket库所占用的系统资源。
1.6 demo
#include <stdio.h>
#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib")
int main(void)
{
WORD wdVersion = MAKEWORD(2, 1); //声明调用的winsock版本 MAKEWORD 创建一个无符号整型,通过链接给定的无符号参数
WSADATA wdSockMsg;
//LPWSADATA lpw = malloc(sizeof(WSADATA));
//WSAStartup(wdVersion, lpw); //windows编程中以LP/P开头需传递对应的地址
int res = WSAStartup(wdVersion, &wdSockMsg);
if (0 != res)
{
switch (res)
{
case WSASYSNOTREADY:
printf("重启电脑");
break;
case WSAVERNOTSUPPORTED:
printf("更新网络库");
break;
case WSAEINPROGRESS:
printf("重新启动");
break;
case WSAEPROCLIM:
printf("关掉不必要的软件");
break;
default:
break;
}
}
//版本校验
if (2 != HIBYTE(wdSockMsg.wVersion) || 2 != LOBYTE(wdSockMsg.wVersion))
{
printf("版本不对");
//关闭网络库
WSACleanup();
return 0;
}
WSACleanup();
system("pause");
return 0;
}