NoteDeep

网络头文件、网络库:

打开网络库:

校验版本:

创建socket:

绑定地址端口:

开始监听:

事件选择模型:

创建事件

函数
WSAEVENT WSAAPI WSACreateEvent();

返回值
失败:WSA_INVALID_EVENT
成功:事件

WSAEVENT转定义是HANDLE, 本质就是void *
句柄:ID、内核对象
内核对象(kernel object:在操作系统的空间申请的对象, 程序相当于操作系统的函数, 内核对象对于程序来说相当于全局变量
由操作系统申请, 由操作系统访问, 不能定位, 不能修改, void *通用类型指针, 不告诉你真正的类型是什么
调用函数创建, 调用函数释放(内核内存泄漏, 只能重启电脑, 普通内存泄漏重启软件就可以)
端口、socket等都是内核对象, 都是是有限的

释放事件:

函数
BOOL WSAAPI WSACloseEvent(
WSAEVENT hEvent
);

eg
WSAEVENT eventServer = WSACreateEvent();
if (WSA_INVALID_EVENT == eventServer)
{
closesocket(sockServer);
WSACleanup();

return 0;
}

绑定并投递:

函数
int WSAAPI WSAEventSelect(
SOCKET s,
WSAEVENT hEventObject,
long lNetworkEvents
);

参数
1.被绑定的socket
2.被绑定的事件
3.需要监视的具体的事件
FD_ACCEPT:有客户端连接, 与服务器socket绑定
FD_READ:有客户端发来消息, 与客户端socket绑定, 用按位或并列使用
FD_CLOSE:客户端下线(包含强制下线、正常下线), 与客户端socket绑定
FD_WRITE:可以给客户端发送消息, 与客户端socket绑定, 会在客户端accept后立刻产生, 只产生一次
FD_CONNECT:客户端一方, 与服务器socket绑定
0:取消事件监视
FD_OOB:带外事件X
FD_QOS:套接字服务质量状态发生变化消息通知, 例如网络发生拥堵
函数:得到服务质量信息
int WSAAPI WSAIoctl(
SOCKET s,
DWORD dwIoControlCode,
LPVOID lpvInBuffer,
DWORD cbInBuffer,
LPVOID lpvOutBuffer,
DWORD cbOutBuffer,
LPDWORD lpcbBytesReturned,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);
eg:
char *strOut[2048] = { 0 };
DWORD nLen = 2048;
WSAIcotl(socketServer, SIO_QOS, 0, 0, strOut, nLen, &nLen, NULL, NULL);
FD_GROUP_QOS:保留(还没用)
FD_ROUTING_INTERFACE_CHANGE:建议应用在重叠I/O中, 数据最优线路改变, 路由接口改变, 要通过WSAIcotl(SIO_ROUTING_INTERFACE_CHANGE)注册使用
FD_ADDRESS_LIST_CHANGE:建议应用在重叠I/O中, 想要接受套接字地址组本地地址列表更改通知, 要通过WSAIcotl(SIO_ADDRESS_LIST_CHANGE)注册使用

返回值
成功:0
失败:SOCKET_ERROR

eg
if (SOCKET_ERROR == WSAEventSelect(sockServer, eventServer, FD_ACCEPT))
{
int errorcode = WSAGetLastError();

WSACloseEvent(eventServer);
closesocket(sockServer);
WSACleanup();

return 0;
}

等待/询问事件:

定义结构体
socket数组、事件数组、计数
struct fd_es_set
{
u_short fd_count;
SOCKET fd_sockarr[WSA_MAXIMUM_WAIT_EVENTS];
WSAEVENT fd_eventarr[WSA_MAXIMUM_WAIT_EVENTS];
};

函数
DWORD WSAAPI WSAWaitForMultipleEvents(
DWORD cEvents,
const WSAEVENT *lphEvents,
BOOL fWaitAll,
DWORD dwTimeout,
BOOL fAlertable
);

参数
1.事件个数
2.事件数组
3.事件等待方式:
TRUE:所有事件都产生信号才返回
FALSE:任何一个事件产生信号立即返回
返回值 - WSA_WAIT_EVENT_0表示事件的对象索引
如果调用期间多个事件发生信号, 返回下标最小的
4.超时间隔:
毫秒, 如果没有一个有信号所等待的时间, 超时返回 WSA_WAIT_TIMEOUT
0:立即返回, 不等待
WSA_INFINITE:等待直到事件的发生
5.TRUE:重叠I/O中的完成例程使用
FALSE:事件select模型

返回值
数组下标的运算值:参数3为需要设置为false-->返回值 - WSA_WAAIT_EVENT_0 == 数组下标
WSA_WAIT_IO_COMPLETION:重叠IO的返回值
WSA_WAIT_TIMEOUT:超时, 没有事件有信号, continue
调用失败:WSA_WAIT_FAILED

eg
while (1)
{
DWORD nRes = WSAWaitForMultipleEvents(esset.fd_count, esset.fd_eventarr, FALSE, WSA_INFINITE, FALSE);

if (WSA_WAIT_FAILED == nRes)
{
int errorcode = WSAGetLastError();
printf("errorcode : %d\n", errorcode);
break;
}
// 超时使用
/*if (WSA_WAIT_TIMEOUT == nRes)
{
continue;
}*/

DWORD nIndex = nRes - WSA_WAIT_EVENT_0;
}

列举事件:

获取事件类型, 并将事件上的信号重置:accept、recv、close。
函数
int WSAAPI WSAEnumNetworkEvents(
SOCKET s,
WSAEVENT hEventObject,
LPWSANETWORKEVENTS lpNetworkEvents
);

参数
1.对应的socket
2.对应的事件
3.触发的事件类型的指针:
typedef struct _WSANETWORKEVENTS {
long lNetworkEvents;
int iErrorCode[FD_MAX_EVENTS];
} WSANETWORKEVENTS, *LPWSANETWORKEVENTS;
lNetworkEvents:具体的事件(多个事件按位或可能会和一个事件冲突:FD_READ | FD_WRITE == FD_ACCEPT_BIT)
iErrorCode[FD_MAX_EVENTS]:错误码数组, 对应的错误码装在对应的错误宏位置(作为下标, 在事件后面加上_BIT)中

FD_WRITE事件:
FD_WRITE:只在accept之后立即产生一次, 可以用来初始化客户端初始化


返回值
成功:0
错误:SOCKET_ERROR, WSAGetLastError()

释放所有的socket和event



事件函数:

关闭释放事件句柄
BOOL WSAAPI WSACloseEvent(
WSAEVENT hEvent
);
重置WSAEventSelect使用的事件的状态
BOOL WSAAPI WSAResetEvent(
WSAEVENT hEvent
);
将指定的事件置为有信号
BOOL WSAAPI WSASetEvent(
WSAEVENT hEvent
);











评论列表

    网络头文件、网络库:
    打开网络库:
    校验版本:
    创建socket:
    绑定地址端口:
    开始监听:
    事件选择模型:
    事件函数: