下标相同的绑定成一组(事件数组也可以直接用重叠结构中的事件)
投递WSARecv:立即完成(再次投递)、延迟完成(循环等待)
投递WSASend:(根据需求)立即完成、延迟完成(循环等待)
等信号:WSAWaitForMultipleEvents
获取重叠结构中的信息:WSAGetOverlappedResult
网络头文件、网络库:
打开网络库:
校验版本:
创建socket:
SOCKET WSAAPI WSASocketA(
int af,
int type,
int protocol,
LPWSAPROTOCOL_INFOA lpProtocolInfo,
GROUP g,
DWORD dwFlags
);
发送数据是否需要链接(TCP需要先链接才能发送, 而UDP不需要)
如果参数3是0:(多个匹配的协议)可以设置匹配的协议
5.保留:0, 一组socket组ID, 一次操作多个socket
WSA_FLAG_OVERLAPPED:供重叠IO使用的socket
用于多播:
WSA_FLAG_MULTIPOINT_C_ROOT
WSA_FLAG_MULTIPOINT_C_LEAF
WSA_FLAG_MULTIPOINT_D_ROOT
WSA_FLAG_MULTIPOINT_D_LEAF
WSA_FLAG_ACCESS_SYSTEM_SECURITY:套接字设置send操作权限, send时会触发相应的操作权限提醒
WSA_FLAG_NO_HANDLE_INHERIT:
套接字不可继承, 多线程开发中, 子线程会继承父线程的socket, 子线程使用socket的方式:1.父子使用同一个(共享) 2.子线程复制一份使用(继承:释放两次)
BOOL AcceptEx(
SOCKET sListenSocket,
SOCKET sAcceptSocket,
PVOID lpOutputBuffer,
DWORD dwReceiveDataLength,
DWORD dwLocalAddressLength,
DWORD dwRemoteAddressLength,
LPDWORD lpdwBytesReceived,
LPOVERLAPPED lpOverlapped
);
2.客户端socket(创建socket, 将socket放在这里即可)
(和Accept区别:Accept(创建客户端socket、绑定bind)AcceptEx(仅提供绑定, 需要自己创建))
3.缓冲区指针, 接收在新链接上发送到的第一个数据, 不能设置为NULL
4.缓冲区大小, 如果取消这个缓冲区的功能, 填 0
5.为本地地址信息保留的字节数, 必须至少比使用的传输协议的最大地址长度大16字节
sizeof(struct sockaddr_in) + 16 // 本地存储的地址信息内存大小
6.为远程地址信息保留的字节数, 必须至少比使用的传输协议的最大地址长度大16字节, 不能为 0
sizeof(struct sockaddr_in) + 16 // 临时存储的地址信息内存大小
7.配合参数3和参数4, AcceptEx立即执行时, 第一次发来的字节数
错误码:ERROR_IO_PENDING:异步等待
int WSAAPI WSARecv(
SOCKET s,
LPWSABUF lpBuffers,
DWORD dwBufferCount,
LPDWORD lpNumberOfBytesRecvd,
LPDWORD lpFlags,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);
typedef struct _WSABUF {
ULONG len;
CHAR *buf;
} WSABUF, *LPWSABUF;
5.指向修改WSARecv函数调用行为的标志的指针, 和recv参数5一样
MSG_PEEK:将协议缓冲区中的数据复制出来, 但是不删除
MSG_PUSH_IMMEDIATE:通知传送尽快完成, 可能会舍弃造成数据丢失, 不能用于大文件的发送, 聊天没问题(会减少一定的延迟)
MSG_WAITALL:直到缓冲区装满, 才会产生信号
MSG_PARTIAL:(传出的参数)表示此次接收的数据是一部分, 接下来将接收下一部分
ERROR_IO_PENDING:延迟处理(WSA_IO_PENDING)
int WSAAPI WSASend(
SOCKET s,
LPWSABUF lpBuffers,
DWORD dwBufferCount,
LPDWORD lpNumberOfBytesSent,
DWORD dwFlags,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);
DWORD WSAAPI WSAWaitForMultipleEvents(
DWORD cEvents,
const WSAEVENT *lphEvents,
BOOL fWaitAll,
DWORD dwTimeout,
BOOL fAlertable
);
返回值 - WSA_WAIT_EVENT_0表示事件的对象索引
毫秒, 如果没有一个有信号所等待的时间, 超时返回 WSA_WAIT_TIMEOUT
数组下标的运算值:参数3为需要设置为false-->返回值 - WSA_WAAIT_EVENT_0 == 数组下标
WSA_WAIT_IO_COMPLETION:重叠IO的返回值
WSA_WAIT_TIMEOUT:超时, 没有事件有信号, continue
BOOL WSAAPI WSAGetOverlappedResult(
SOCKET s,
LPWSAOVERLAPPED lpOverlapped,
LPDWORD lpcbTransfer,
BOOL fWait,
LPDWORD lpdwFlags
);
FALSE:失败, WSAGetLastError, 10054是客户端强制退出