1 windows处理用户行为的两种方式
2 事件选择的原理
3 事件选择步骤
3.1 处理事件的几个函数
3.1.1 创建一个事件对象 WSACreateEvent()
使用WSACreateEvent 函数创建一个新的事件对象。
语法
WSAEVENT WSAAPI WSACreateEvent();
返回值 如果未发生错误,WSACreateEvent 将返回事件对象的句柄。否则,返回值将WSA_INVALID_EVENT。要获取扩展的错误信息,请使用 WSAGetLastError。
内核对象
WSAEVENT event_server = WSACreateEvent();
if (WSA_INVALID_EVENT == event_server)
{
printf("event_server error,error_code:%d\n", WSAGetLastError());
closesocket(socket_server);
WSACleanup();
return -1;
}
3.1.2 释放事件 WSACloseEvent()
WSACloseEvent 函数关闭事件对象的句柄,并释放与该事件对象关联的资源。此函数用于关闭由 WSACreateEvent 函数创建的句柄。关闭事件对象的句柄后,对此句柄的进一步引用将失败,错误WSA_INVALID_HANDLE。 语法
BOOL WSAAPI WSACloseEvent(
[in] WSAEVENT hEvent
);
参数
[in] hEvent
标识打开事件的对象句柄。
返回值
- 如果函数成功,则返回值为 TRUE。
- 如果函数失败,则返回值为 FALSE。要获取扩展的错误信息,请使用WSAGetLastError。
3.1.3 WSASetEvent 函数
WSASetEvent 函数将指定事件对象的状态设置为"已发出信号" 语法
BOOL WSAAPI WSASetEvent(
[in] WSAEVENT hEvent
);
参数 [in] hEvent
标识打开的事件对象的句柄。
返回值
- 如果函数成功,则返回值为 TRUE。
- 如果函数失败,则返回值为 FALSE。要获取扩展的错误信息,请使用 WSAGetLastError。
3.1.4 WSAResetEvent 函数
WSAResetEvent 函数将指定事件对象的状态重置为非信号。 语法
BOOL WSAAPI WSAResetEvent(
[in] WSAEVENT hEvent
);
参数 [in] hEvent 标识打开的事件对象句柄的句柄。 返回值
- 如果 WSAResetEvent 函数成功,则返回值为 TRUE。
- 如果函数失败,则返回值为 FALSE。要获取扩展的错误信息,请使用 WSAGetLastError。
3.2 绑定并投递
给事件绑上socket与操作码,并投递给操作系统
WSAEventSelect 函数指定要与指定的一组FD_XXX网络事件相关联的事件对象。 语法
int WSAAPI WSAEventSelect(
[in] SOCKET s,
[in] WSAEVENT hEventObject,
[in] long lNetworkEvents
);
参数
[in] s
标识套接字的描述符。
[in] hEventObject
标识要与指定的FD_XXX网络事件集关联的事件对象的句柄。
[in] lNetworkEvents
一个位掩码,它指定应用程序感兴趣的FD_XXX网络事件的组合。
返回值
- 如果应用程序对网络事件和关联事件对象的规范成功,则返回值为零。
- 否则,将返回值 SOCKET_ERROR,并且可以通过调用 WSAGetLastError 来检索特定的错误号。
3.3 询问事件 WSAWaitForMultipleEvents
当一个或所有指定的事件对象处于信号状态、超时间隔过期或执行 I/O 完成例程时,WSAWaitForMultipleEvents 函数将返回。 语法
DWORD WSAAPI WSAWaitForMultipleEvents(
[in] DWORD cEvents,
[in] const WSAEVENT *lphEvents,
[in] BOOL fWaitAll,
[in] DWORD dwTimeout,
[in] BOOL fAlertable
);
参数 [in] cEvents lphEvents 所指向的数组中的事件对象句柄数。最大事件对象句柄数为 WSA_MAXIMUM_WAIT_EVENTS。必须指定一个或多个事件。
[in] lphEvents 指向事件对象句柄数组的指针。数组可以包含不同类型的对象的句柄。如果 fWaitAll 参数设置为 TRUE,则它可能不包含同一句柄的多个副本。如果其中一个句柄在等待仍处于挂起状态时关闭,则 WSAWaitForMultipleEvents 的行为是未定义的。
句柄必须具有"同步"访问权限。有关详细信息,请参阅标准访问权限。
[in] fWaitAll 指定等待类型的值。
- 如果为 TRUE,则在向 lphEvents 数组中所有对象的状态发出信号时返回该函数。
阻塞 - 如果为 FALSE,则在向任何事件对象发出信号时返回该函数。在后一种情况下,返回值减去 WSA_WAIT_EVENT_0 表示其状态导致函数返回的事件对象的索引。如果在调用期间发出了多个事件对象的信号,则这是指向已发出信号事件对象的数组索引,其索引值是所有已信令事件对象中最小的。
[in] dwTimeout 超时间隔,以毫秒为单位。如果超时间隔过期,WSAWaitForMultipleEvents 将返回,即使不满足 fWaitAll 参数指定的条件也是如此。如果 dwTimeout 参数为零,则 WSAWaitForMultipleEvents 将测试指定事件对象的状态并立即返回。如果 dwTimeout WSA_INFINITE,WSAWaitForMultipleEvents 将永远等待;也就是说,超时间隔永不过期。
[in] fAlertable 一个值,该值指定是否将线程置于可警报的等待状态,以便系统可以执行 I/O 完成例程。如果为 TRUE,则线程将置于可警报的等待状态,并且当系统执行 I/O 完成例程时,WSAWaitForMultipleEvents 可以返回。在这种情况下,将返回WSA_WAIT_IO_COMPLETION,并且尚未发出正在等待的事件的信号。应用程序必须再次调用 WSAWaitForMultipleEvents 函数。如果为 FALSE,则线程不会处于可警报的等待状态,并且不会执行 I/O 完成例程。
返回值 如果 WSAWaitForMultipleEvents 函数成功,则成功时的返回值是以下值之一。
返回值 | 意义 |
---|
WSA_WAIT_EVENT_0到 (WSA_WAIT_EVENT_0 + c事件 - 1) | 如果 fWaitAll 参数为 TRUE,则返回值指示所有指定的事件对象都已发出信号。 如果 fWaitAll 参数为 FALSE,则返回值减去 WSA_WAIT_EVENT_0 指示满足等待的已发出信号的事件对象的 lphEvents 数组索引。如果在调用期间有多个事件对象发出信号,则返回值指示已发出信号事件对象的 lphEvents 数组索引,其索引值是所有已发出信号事件对象的最小索引值。 | WSA_WAIT_IO_COMPLETION | 等待已由一个或多个已执行的 I/O 完成例程结束。正在等待的事件尚未发出信号。应用程序必须再次调用 WSAWaitForMultipleEvents 函数。仅当 fAlertable 参数为 TRUE 时,才能返回此返回值。 | WSA_WAIT_TIMEOUT | 未满足已过的超时间隔和 fWaitAll 参数指定的条件。未执行任何 I/O 完成例程。 |
如果 WSAWaitForMultipleEvents 函数失败,则返回值为 WSA_WAIT_FAILED。
event_server.c
#define _CRT_SECURE_NO_WARNINGS
#include <WinSock2.h>
#include <stdio.h>
#pragma comment(lib,"Ws2_32.lib")
typedef struct fd_event_socket_set
{
unsigned short count;
SOCKET all_sock[WSA_MAXIMUM_WAIT_EVENTS];
WSAEVENT all_event[WSA_MAXIMUM_WAIT_EVENTS];
};
fd_set fd_set_socks;
BOOL WINAPI fun(DWORD dw_ctrl_type)
{
switch (dw_ctrl_type)
{
case CTRL_CLOSE_EVENT:
{
{
}
}
break;
default:
break;
}
return TRUE;
}
int main(int argc, char* argv[])
{
SetConsoleCtrlHandler(fun, TRUE);
WORD ws_verson = MAKEWORD(2, 2);
WSADATA wd_sock_msg;
int ret = WSAStartup(ws_verson, &wd_sock_msg);
if (0 != ret)
{
switch (ret)
{
case WSASYSNOTREADY:
printf("重启下电脑试试,或者检查网络库!");
break;
case WSAVERNOTSUPPORTED:
printf("请更新网络库!");
break;
case WSAEPROCLIM:
printf("请重新启动!");
break;
case WSAEINPROGRESS:
printf("请尝试关掉不必要的软件,为当前网络运行提供充足资源!");
break;
case WSAEFAULT:
printf("参数错误!");
break;
default:
break;
}
return 0;
}
printf("网络库打开成功!\n");
if (2 != LOBYTE(wd_sock_msg.wVersion) ||
2 != HIBYTE(wd_sock_msg.wVersion))
{
WSACleanup();
return -1;
}
printf("网络库版本号:(%d,%d)\n", LOBYTE(wd_sock_msg.wVersion), HIBYTE(wd_sock_msg.wVersion));
SOCKET socket_server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (INVALID_SOCKET == socket_server)
{
printf("socket created failed,error_code:%d\n", WSAGetLastError());
WSACleanup();
return -1;
}
else
printf("socket created success,return code:%d\n", socket_server);
struct sockaddr_in si;
si.sin_family = AF_INET;
si.sin_port = htons(12345);
si.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
int res_bind = bind(socket_server, (const struct sockaddr *) &si, sizeof(si));
if (SOCKET_ERROR == res_bind)
{
printf("bind failed,error_code:%d\n", WSAGetLastError());
closesocket(socket_server);
WSACleanup();
return -1;
}
else
printf("bind success,return code:%d\n", res_bind);
int res_listen = listen(socket_server, SOMAXCONN);
if (SOCKET_ERROR == res_listen)
{
printf("listen failed,error_code:%d\n", WSAGetLastError());
closesocket(socket_server);
WSACleanup();
return -1;
}
else
printf("listen success,return code:%d\n", res_listen);
struct fd_event_socket_set fd_es_set = { 0, { 0 }, { NULL } };
WSAEVENT server_event = WSACreateEvent();
if (WSA_INVALID_EVENT == server_event)
{
printf("event_server error,error_code:%d\n", WSAGetLastError());
closesocket(socket_server);
WSACleanup();
return -1;
}
int res_event_select = WSAEventSelect(socket_server, server_event, FD_ACCEPT);
if (SOCKET_ERROR == res_event_select)
{
printf("event_select error,error_code:%d\n", WSAGetLastError());
BOOL colse_event_flag = WSACloseEvent(server_event);
if (TRUE == colse_event_flag)
{
printf("event_server close success\n");
}
else if (FALSE == colse_event_flag)
{
printf("event_server close failed,error_code:%d\n", WSAGetLastError());
}
closesocket(socket_server);
WSACleanup();
return -1;
}
fd_es_set.all_event[fd_es_set.count] = server_event;
fd_es_set.all_sock[fd_es_set.count] = socket_server;
fd_es_set.count++;
while (1)
{
DWORD res_wait = WSAWaitForMultipleEvents(fd_es_set.count,
fd_es_set.all_event,
FALSE,
120,
FALSE);
if (WSA_WAIT_FAILED == res_wait)
{
printf("WSAWaitForMultipleEvents error, error_code:%d\n", WSAGetLastError());
break;
}
if (WSA_WAIT_TIMEOUT == res_wait)
{
printf("time out : %d\n", res_wait);
continue;
}
DWORD index = res_wait - WSA_WAIT_EVENT_0;
}
BOOL colse_event_flag = WSACloseEvent(server_event);
if (TRUE == colse_event_flag)
{
printf("event_server close success\n");
}
else if (FALSE == colse_event_flag)
{
printf("event_server close failed,error_code:%d\n", WSAGetLastError());
}
closesocket(socket_server);
WSACleanup();
printf("\n");
system("pause");
return 0;
}
3.4 列举事件
event_server.c
#define _CRT_SECURE_NO_WARNINGS
#include <WinSock2.h>
#include <stdio.h>
#pragma comment(lib,"Ws2_32.lib")
typedef struct fd_event_socket_set
{
unsigned short count;
SOCKET all_sock[WSA_MAXIMUM_WAIT_EVENTS];
WSAEVENT all_event[WSA_MAXIMUM_WAIT_EVENTS];
};
fd_set fd_set_socks;
BOOL WINAPI fun(DWORD dw_ctrl_type)
{
switch (dw_ctrl_type)
{
case CTRL_CLOSE_EVENT:
{
{
}
}
break;
default:
break;
}
return TRUE;
}
int main(int argc, char* argv[])
{
SetConsoleCtrlHandler(fun, TRUE);
WORD ws_verson = MAKEWORD(2, 2);
WSADATA wd_sock_msg;
int ret = WSAStartup(ws_verson, &wd_sock_msg);
if (0 != ret)
{
switch (ret)
{
case WSASYSNOTREADY:
printf("重启下电脑试试,或者检查网络库!");
break;
case WSAVERNOTSUPPORTED:
printf("请更新网络库!");
break;
case WSAEPROCLIM:
printf("请重新启动!");
break;
case WSAEINPROGRESS:
printf("请尝试关掉不必要的软件,为当前网络运行提供充足资源!");
break;
case WSAEFAULT:
printf("参数错误!");
break;
default:
break;
}
return 0;
}
printf("网络库打开成功!\n");
if (2 != LOBYTE(wd_sock_msg.wVersion) ||
2 != HIBYTE(wd_sock_msg.wVersion))
{
WSACleanup();
return -1;
}
printf("网络库版本号:(%d,%d)\n", LOBYTE(wd_sock_msg.wVersion), HIBYTE(wd_sock_msg.wVersion));
SOCKET socket_server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (INVALID_SOCKET == socket_server)
{
printf("socket created failed,error_code:%d\n", WSAGetLastError());
WSACleanup();
return -1;
}
else
printf("socket created success,return code:%d\n", socket_server);
struct sockaddr_in si;
si.sin_family = AF_INET;
si.sin_port = htons(12345);
si.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
int res_bind = bind(socket_server, (const struct sockaddr *) &si, sizeof(si));
if (SOCKET_ERROR == res_bind)
{
printf("bind failed,error_code:%d\n", WSAGetLastError());
closesocket(socket_server);
WSACleanup();
return -1;
}
else
printf("bind success,return code:%d\n", res_bind);
int res_listen = listen(socket_server, SOMAXCONN);
if (SOCKET_ERROR == res_listen)
{
printf("listen failed,error_code:%d\n", WSAGetLastError());
closesocket(socket_server);
WSACleanup();
return -1;
}
else
printf("listen success,return code:%d\n", res_listen);
struct fd_event_socket_set fd_es_set = { 0, { 0 }, { NULL } };
WSAEVENT server_event = WSACreateEvent();
if (WSA_INVALID_EVENT == server_event)
{
printf("event_server error,error_code:%d\n", WSAGetLastError());
closesocket(socket_server);
WSACleanup();
return -1;
}
int res_event_select = WSAEventSelect(socket_server, server_event, FD_ACCEPT);
if (SOCKET_ERROR == res_event_select)
{
printf("event_select error,error_code:%d\n", WSAGetLastError());
BOOL colse_event_flag = WSACloseEvent(server_event);
if (TRUE == colse_event_flag)
{
printf("event_server close success\n");
}
else if (FALSE == colse_event_flag)
{
printf("event_server close failed,error_code:%d\n", WSAGetLastError());
}
closesocket(socket_server);
WSACleanup();
return -1;
}
fd_es_set.all_event[fd_es_set.count] = server_event;
fd_es_set.all_sock[fd_es_set.count] = socket_server;
fd_es_set.count++;
while (1)
{
DWORD res_wait = WSAWaitForMultipleEvents(fd_es_set.count,
fd_es_set.all_event,
FALSE,
120,
FALSE);
if (WSA_WAIT_FAILED == res_wait)
{
printf("WSAWaitForMultipleEvents error, error_code:%d\n", WSAGetLastError());
break;
}
if (WSA_WAIT_TIMEOUT == res_wait)
{
printf("time out : %d\n", res_wait);
continue;
}
DWORD index = res_wait - WSA_WAIT_EVENT_0;
WSANETWORKEVENTS network_events;
int res_enum_events = WSAEnumNetworkEvents(fd_es_set.all_sock[index],
fd_es_set.all_event[index],
&network_events);
if (SOCKET_ERROR == res_enum_events)
{
printf("WSAEnumNetworkEvents error, error_code:%d\n", res_enum_events);
break;
}
}
BOOL colse_event_flag = WSACloseEvent(server_event);
if (TRUE == colse_event_flag)
{
printf("event_server close success\n");
}
else if (FALSE == colse_event_flag)
{
printf("event_server close failed,error_code:%d\n", WSAGetLastError());
}
closesocket(socket_server);
WSACleanup();
printf("\n");
system("pause");
return 0;
}
3.5 事件的分类处理
test_demo event_select_server.c
#define _CRT_SECURE_NO_WARNINGS
#include <WinSock2.h>
#include <stdio.h>
#pragma comment(lib,"Ws2_32.lib")
typedef struct fd_event_socket_set
{
unsigned short count;
SOCKET all_sock[WSA_MAXIMUM_WAIT_EVENTS];
WSAEVENT all_event[WSA_MAXIMUM_WAIT_EVENTS];
};
fd_set fd_set_socks;
BOOL WINAPI fun(DWORD dw_ctrl_type)
{
switch (dw_ctrl_type)
{
case CTRL_CLOSE_EVENT:
{
{
}
}
break;
default:
break;
}
return TRUE;
}
int main(int argc, char* argv[])
{
SetConsoleCtrlHandler(fun, TRUE);
WORD ws_verson = MAKEWORD(2, 2);
WSADATA wd_sock_msg;
int ret = WSAStartup(ws_verson, &wd_sock_msg);
if (0 != ret)
{
switch (ret)
{
case WSASYSNOTREADY:
printf("重启下电脑试试,或者检查网络库!");
break;
case WSAVERNOTSUPPORTED:
printf("请更新网络库!");
break;
case WSAEPROCLIM:
printf("请重新启动!");
break;
case WSAEINPROGRESS:
printf("请尝试关掉不必要的软件,为当前网络运行提供充足资源!");
break;
case WSAEFAULT:
printf("参数错误!");
break;
default:
break;
}
return 0;
}
printf("网络库打开成功!\n");
if (2 != LOBYTE(wd_sock_msg.wVersion) ||
2 != HIBYTE(wd_sock_msg.wVersion))
{
WSACleanup();
return -1;
}
printf("网络库版本号:(%d,%d)\n", LOBYTE(wd_sock_msg.wVersion), HIBYTE(wd_sock_msg.wVersion));
SOCKET socket_server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (INVALID_SOCKET == socket_server)
{
printf("socket_server created failed,error_code:%d\n", WSAGetLastError());
WSACleanup();
return -1;
}
else
printf("socket_server created success,return code:%d\n", socket_server);
struct sockaddr_in si;
si.sin_family = AF_INET;
si.sin_port = htons(12345);
si.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
int res_bind = bind(socket_server, (const struct sockaddr *) &si, sizeof(si));
if (SOCKET_ERROR == res_bind)
{
printf("bind failed,error_code:%d\n", WSAGetLastError());
closesocket(socket_server);
WSACleanup();
return -1;
}
else
printf("bind success,return code:%d\n", res_bind);
int res_listen = listen(socket_server, SOMAXCONN);
if (SOCKET_ERROR == res_listen)
{
printf("listen failed,error_code:%d\n", WSAGetLastError());
closesocket(socket_server);
WSACleanup();
return -1;
}
else
printf("listen success,return code:%d\n", res_listen);
struct fd_event_socket_set fd_es_set = { 0, { 0 }, { NULL } };
WSAEVENT server_event = WSACreateEvent();
if (WSA_INVALID_EVENT == server_event)
{
printf("event_server error,error_code:%d\n", WSAGetLastError());
closesocket(socket_server);
WSACleanup();
return -1;
}
int res_server_event_select = WSAEventSelect(socket_server, server_event, FD_ACCEPT);
if (SOCKET_ERROR == res_server_event_select)
{
printf("server_event_select error,error_code:%d\n", WSAGetLastError());
BOOL colse_event_flag = WSACloseEvent(server_event);
if (TRUE == colse_event_flag)
{
printf("server_event close success\n");
}
else if (FALSE == colse_event_flag)
{
printf("server_event close failed,error_code:%d\n", WSAGetLastError());
}
closesocket(socket_server);
WSACleanup();
return -1;
}
fd_es_set.all_event[fd_es_set.count] = server_event;
fd_es_set.all_sock[fd_es_set.count] = socket_server;
fd_es_set.count++;
while (1)
{
DWORD res_wait_event = WSAWaitForMultipleEvents(fd_es_set.count,
fd_es_set.all_event,
FALSE,
WSA_INFINITE ,
FALSE);
if (WSA_WAIT_FAILED == res_wait_event)
{
printf("WSAWaitForMultipleEvents error, error_code:%d\n", WSAGetLastError());
break;
}
DWORD index = res_wait_event - WSA_WAIT_EVENT_0;
WSANETWORKEVENTS network_events;
int res_enum_events = WSAEnumNetworkEvents(fd_es_set.all_sock[index],
fd_es_set.all_event[index],
&network_events);
if (SOCKET_ERROR == res_enum_events)
{
printf("WSAEnumNetworkEvents error, error_code:%d\n", res_enum_events);
break;
}
if (network_events.lNetworkEvents & FD_ACCEPT)
{
if (0 == network_events.iErrorCode[FD_ACCEPT_BIT])
{
SOCKET socket_client = accept(fd_es_set.all_sock[index], NULL, NULL);
if (INVALID_SOCKET == socket_client)
{
continue;
}
WSAEVENT wsa_client_event = WSACreateEvent();
if (WSA_INVALID_EVENT == wsa_client_event)
{
closesocket(socket_client);
continue;
}
int res_client_event_select = WSAEventSelect(socket_client,
wsa_client_event,
FD_READ | FD_CLOSE | FD_WRITE);
if (SOCKET_ERROR == res_client_event_select)
{
printf("client_event_select error,error_code:%d\n", WSAGetLastError());
BOOL colse_event_flag = WSACloseEvent(wsa_client_event);
if (TRUE == colse_event_flag)
{
printf("wsa_client_event close success\n");
}
else if (FALSE == colse_event_flag)
{
printf("wsa_client_event close failed,error_code:%d\n", WSAGetLastError());
}
closesocket(socket_client);
WSACleanup();
return -1;
}
fd_es_set.all_sock[fd_es_set.count] = socket_client;
fd_es_set.all_event[fd_es_set.count] = wsa_client_event;
fd_es_set.count++;
printf("accept event\n");
}
else
{
printf("network_events FD_ACCEPT | socket error, error_code:%d\n",
network_events.iErrorCode[FD_ACCEPT_BIT]);
continue;
}
}
if (network_events.lNetworkEvents & FD_WRITE)
{
if (0 == network_events.iErrorCode[FD_WRITE_BIT])
{
int res_send = send(fd_es_set.all_sock[index], "connect success",
strlen("connect success"), 0);
if (SOCKET_ERROR == res_send)
{
printf("send error, error_code:%d\n", WSAGetLastError());
continue;
}
printf("write event\n");
}
else
{
printf("network_events FD_WRITE | socket error, error_code:%d\n",
network_events.iErrorCode[FD_WRITE_BIT]);
continue;
}
}
if (network_events.lNetworkEvents & FD_READ)
{
if (0 == network_events.iErrorCode[FD_READ_BIT])
{
char recv_buf[1500] = { 0 };
int res_recv = recv(fd_es_set.all_sock[index], recv_buf, 1499, 0);
if (SOCKET_ERROR == res_recv)
{
printf("recv error, error_code:%d\n", WSAGetLastError());
continue;
}
printf("recv data:%s\n", recv_buf);
}
else
{
printf("network_events FD_READ | socket error, error_code:%d\n",
network_events.iErrorCode[FD_READ_BIT]);
}
}
if (network_events.lNetworkEvents & FD_CLOSE)
{
printf("client close\n");
printf("network_events FD_CLOSE | socket error, error_code:%d\n",
network_events.iErrorCode[FD_CLOSE_BIT]);
closesocket(fd_es_set.all_sock[index]);
fd_es_set.all_sock[index] = fd_es_set.all_sock[fd_es_set.count - 1];
WSACloseEvent(fd_es_set.all_event[index]);
fd_es_set.all_event[index] = fd_es_set.all_event[fd_es_set.count - 1];
fd_es_set.count--;
}
}
BOOL colse_event_flag = WSACloseEvent(server_event);
if (TRUE == colse_event_flag)
{
printf("event_server close success\n");
}
else if (FALSE == colse_event_flag)
{
printf("event_server close failed,error_code:%d\n", WSAGetLastError());
}
closesocket(socket_server);
WSACleanup();
printf("\n");
system("pause");
return 0;
}
client.c
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <Winsock2.h>
#pragma comment(lib, "Ws2_32.lib")
int main(void)
{
WORD wdVersion = MAKEWORD(2, 2);
WSADATA wdScokMsg;
int nRes = WSAStartup(wdVersion, &wdScokMsg);
if (0 != nRes)
{
switch (nRes)
{
case WSASYSNOTREADY:
printf("重启下电脑试试,或者检查网络库");
break;
case WSAVERNOTSUPPORTED:
printf("请更新网络库");
break;
case WSAEINPROGRESS:
printf("请重新启动");
break;
case WSAEPROCLIM:
printf("请尝试关掉不必要的软件,以为当前网络运行提供充足资源");
break;
}
return 0;
}
if (2 != HIBYTE(wdScokMsg.wVersion) || 2 != LOBYTE(wdScokMsg.wVersion))
{
WSACleanup();
return 0;
}
SOCKET socketServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (INVALID_SOCKET == socketServer)
{
int a = WSAGetLastError();
WSACleanup();
return 0;
}
struct sockaddr_in serverMsg;
serverMsg.sin_family = AF_INET;
serverMsg.sin_port = htons(12345);
serverMsg.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
if (SOCKET_ERROR == connect(socketServer, (struct sockaddr*)&serverMsg, sizeof(serverMsg)))
{
int a = WSAGetLastError();
closesocket(socketServer);
WSACleanup();
return 0;
}
while (1)
{
char buf[1500] = { 0 };
scanf("%s", buf);
if ('q' == buf[0])
{
break;
}
if (SOCKET_ERROR == send(socketServer, buf, strlen(buf), 0))
{
int a = WSAGetLastError();
printf("%d\n", a);
}
}
closesocket(socketServer);
WSACleanup();
system("pause");
return 0;
}
3.6 有序化之变态点击
3.6.1 优化1
5个客户端轮询,
while(1)
{
1;
2;
3;
4;
5;
}
event_select_server.c
#define _CRT_SECURE_NO_WARNINGS
#include <WinSock2.h>
#include <stdio.h>
#pragma comment(lib,"Ws2_32.lib")
typedef struct fd_event_socket_set
{
unsigned short count;
SOCKET all_sock[WSA_MAXIMUM_WAIT_EVENTS];
WSAEVENT all_event[WSA_MAXIMUM_WAIT_EVENTS];
};
fd_set fd_set_socks;
BOOL WINAPI fun(DWORD dw_ctrl_type)
{
switch (dw_ctrl_type)
{
case CTRL_CLOSE_EVENT:
{
{
}
}
break;
default:
break;
}
return TRUE;
}
int main(int argc, char* argv[])
{
SetConsoleCtrlHandler(fun, TRUE);
WORD ws_verson = MAKEWORD(2, 2);
WSADATA wd_sock_msg;
int ret = WSAStartup(ws_verson, &wd_sock_msg);
if (0 != ret)
{
switch (ret)
{
case WSASYSNOTREADY:
printf("重启下电脑试试,或者检查网络库!");
break;
case WSAVERNOTSUPPORTED:
printf("请更新网络库!");
break;
case WSAEPROCLIM:
printf("请重新启动!");
break;
case WSAEINPROGRESS:
printf("请尝试关掉不必要的软件,为当前网络运行提供充足资源!");
break;
case WSAEFAULT:
printf("参数错误!");
break;
default:
break;
}
return 0;
}
printf("网络库打开成功!\n");
if (2 != LOBYTE(wd_sock_msg.wVersion) ||
2 != HIBYTE(wd_sock_msg.wVersion))
{
WSACleanup();
return -1;
}
printf("网络库版本号:(%d,%d)\n", LOBYTE(wd_sock_msg.wVersion), HIBYTE(wd_sock_msg.wVersion));
SOCKET socket_server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (INVALID_SOCKET == socket_server)
{
printf("socket_server created failed,error_code:%d\n", WSAGetLastError());
WSACleanup();
return -1;
}
else
printf("socket_server created success,return code:%d\n", socket_server);
struct sockaddr_in si;
si.sin_family = AF_INET;
si.sin_port = htons(12345);
si.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
int res_bind = bind(socket_server, (const struct sockaddr *) &si, sizeof(si));
if (SOCKET_ERROR == res_bind)
{
printf("bind failed,error_code:%d\n", WSAGetLastError());
closesocket(socket_server);
WSACleanup();
return -1;
}
else
printf("bind success,return code:%d\n", res_bind);
int res_listen = listen(socket_server, SOMAXCONN);
if (SOCKET_ERROR == res_listen)
{
printf("listen failed,error_code:%d\n", WSAGetLastError());
closesocket(socket_server);
WSACleanup();
return -1;
}
else
printf("listen success,return code:%d\n", res_listen);
struct fd_event_socket_set fd_es_set = { 0, { 0 }, { NULL } };
WSAEVENT server_event = WSACreateEvent();
if (WSA_INVALID_EVENT == server_event)
{
printf("event_server error,error_code:%d\n", WSAGetLastError());
closesocket(socket_server);
WSACleanup();
return -1;
}
int res_server_event_select = WSAEventSelect(socket_server, server_event, FD_ACCEPT);
if (SOCKET_ERROR == res_server_event_select)
{
printf("server_event_select error,error_code:%d\n", WSAGetLastError());
BOOL colse_event_flag = WSACloseEvent(server_event);
if (TRUE == colse_event_flag)
{
printf("server_event close success\n");
}
else if (FALSE == colse_event_flag)
{
printf("server_event close failed,error_code:%d\n", WSAGetLastError());
}
closesocket(socket_server);
WSACleanup();
return -1;
}
fd_es_set.all_event[fd_es_set.count] = server_event;
fd_es_set.all_sock[fd_es_set.count] = socket_server;
fd_es_set.count++;
while (1)
{
for (int index = 0; index < fd_es_set.count; index++)
{
DWORD res_wait_event = WSAWaitForMultipleEvents(1,
&fd_es_set.all_event[index],
FALSE,
0,
FALSE);
if (WSA_WAIT_FAILED == res_wait_event)
{
printf("WSAWaitForMultipleEvents error, error_code:%d\n", WSAGetLastError());
continue;
}
if (WSA_WAIT_TIMEOUT == res_wait_event)
{
continue;
}
WSANETWORKEVENTS network_events;
int res_enum_events = WSAEnumNetworkEvents(fd_es_set.all_sock[index],
fd_es_set.all_event[index],
&network_events);
if (SOCKET_ERROR == res_enum_events)
{
printf("WSAEnumNetworkEvents error, error_code:%d\n", res_enum_events);
break;
}
if (network_events.lNetworkEvents & FD_ACCEPT)
{
if (0 == network_events.iErrorCode[FD_ACCEPT_BIT])
{
SOCKET socket_client = accept(fd_es_set.all_sock[index], NULL, NULL);
if (INVALID_SOCKET == socket_client)
{
continue;
}
WSAEVENT wsa_client_event = WSACreateEvent();
if (WSA_INVALID_EVENT == wsa_client_event)
{
closesocket(socket_client);
continue;
}
int res_client_event_select = WSAEventSelect(socket_client,
wsa_client_event,
FD_READ | FD_CLOSE | FD_WRITE);
if (SOCKET_ERROR == res_client_event_select)
{
printf("client_event_select error,error_code:%d\n", WSAGetLastError());
BOOL colse_event_flag = WSACloseEvent(wsa_client_event);
if (TRUE == colse_event_flag)
{
printf("wsa_client_event close success\n");
}
else if (FALSE == colse_event_flag)
{
printf("wsa_client_event close failed,error_code:%d\n", WSAGetLastError());
}
closesocket(socket_client);
WSACleanup();
return -1;
}
fd_es_set.all_sock[fd_es_set.count] = socket_client;
fd_es_set.all_event[fd_es_set.count] = wsa_client_event;
fd_es_set.count++;
printf("accept event\n");
}
else
{
printf("network_events FD_ACCEPT | socket error, error_code:%d\n",
network_events.iErrorCode[FD_ACCEPT_BIT]);
continue;
}
}
if (network_events.lNetworkEvents & FD_WRITE)
{
if (0 == network_events.iErrorCode[FD_WRITE_BIT])
{
int res_send = send(fd_es_set.all_sock[index], "connect success",
strlen("connect success"), 0);
if (SOCKET_ERROR == res_send)
{
printf("send error, error_code:%d\n", WSAGetLastError());
continue;
}
printf("write event\n");
}
else
{
printf("network_events FD_WRITE | socket error, error_code:%d\n",
network_events.iErrorCode[FD_WRITE_BIT]);
continue;
}
}
if (network_events.lNetworkEvents & FD_READ)
{
if (0 == network_events.iErrorCode[FD_READ_BIT])
{
char recv_buf[1500] = { 0 };
int res_recv = recv(fd_es_set.all_sock[index], recv_buf, 1499, 0);
if (SOCKET_ERROR == res_recv)
{
printf("recv error, error_code:%d\n", WSAGetLastError());
continue;
}
printf("recv data:%s\n", recv_buf);
}
else
{
printf("network_events FD_READ | socket error, error_code:%d\n",
network_events.iErrorCode[FD_READ_BIT]);
}
}
if (network_events.lNetworkEvents & FD_CLOSE)
{
printf("client close\n");
printf("network_events FD_CLOSE | socket error, error_code:%d\n",
network_events.iErrorCode[FD_CLOSE_BIT]);
closesocket(fd_es_set.all_sock[index]);
fd_es_set.all_sock[index] = fd_es_set.all_sock[fd_es_set.count - 1];
WSACloseEvent(fd_es_set.all_event[index]);
fd_es_set.all_event[index] = fd_es_set.all_event[fd_es_set.count - 1];
fd_es_set.count--;
}
}
}
BOOL colse_event_flag = WSACloseEvent(server_event);
if (TRUE == colse_event_flag)
{
printf("event_server close success\n");
}
else if (FALSE == colse_event_flag)
{
printf("event_server close failed,error_code:%d\n", WSAGetLastError());
}
closesocket(socket_server);
WSACleanup();
printf("\n");
system("pause");
return 0;
}
3.6.2 优化2
先得到有事件的下标,再从该客户端下标处轮询 event_select_server.c
#define _CRT_SECURE_NO_WARNINGS
#include <WinSock2.h>
#include <stdio.h>
#pragma comment(lib,"Ws2_32.lib")
typedef struct fd_event_socket_set
{
unsigned short count;
SOCKET all_sock[WSA_MAXIMUM_WAIT_EVENTS];
WSAEVENT all_event[WSA_MAXIMUM_WAIT_EVENTS];
};
fd_set fd_set_socks;
BOOL WINAPI fun(DWORD dw_ctrl_type)
{
switch (dw_ctrl_type)
{
case CTRL_CLOSE_EVENT:
{
{
}
}
break;
default:
break;
}
return TRUE;
}
int main(int argc, char* argv[])
{
SetConsoleCtrlHandler(fun, TRUE);
WORD ws_verson = MAKEWORD(2, 2);
WSADATA wd_sock_msg;
int ret = WSAStartup(ws_verson, &wd_sock_msg);
if (0 != ret)
{
switch (ret)
{
case WSASYSNOTREADY:
printf("重启下电脑试试,或者检查网络库!");
break;
case WSAVERNOTSUPPORTED:
printf("请更新网络库!");
break;
case WSAEPROCLIM:
printf("请重新启动!");
break;
case WSAEINPROGRESS:
printf("请尝试关掉不必要的软件,为当前网络运行提供充足资源!");
break;
case WSAEFAULT:
printf("参数错误!");
break;
default:
break;
}
return 0;
}
printf("网络库打开成功!\n");
if (2 != LOBYTE(wd_sock_msg.wVersion) ||
2 != HIBYTE(wd_sock_msg.wVersion))
{
WSACleanup();
return -1;
}
printf("网络库版本号:(%d,%d)\n", LOBYTE(wd_sock_msg.wVersion), HIBYTE(wd_sock_msg.wVersion));
SOCKET socket_server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (INVALID_SOCKET == socket_server)
{
printf("socket_server created failed,error_code:%d\n", WSAGetLastError());
WSACleanup();
return -1;
}
else
printf("socket_server created success,return code:%d\n", socket_server);
struct sockaddr_in si;
si.sin_family = AF_INET;
si.sin_port = htons(12345);
si.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
int res_bind = bind(socket_server, (const struct sockaddr *) &si, sizeof(si));
if (SOCKET_ERROR == res_bind)
{
printf("bind failed,error_code:%d\n", WSAGetLastError());
closesocket(socket_server);
WSACleanup();
return -1;
}
else
printf("bind success,return code:%d\n", res_bind);
int res_listen = listen(socket_server, SOMAXCONN);
if (SOCKET_ERROR == res_listen)
{
printf("listen failed,error_code:%d\n", WSAGetLastError());
closesocket(socket_server);
WSACleanup();
return -1;
}
else
printf("listen success,return code:%d\n", res_listen);
struct fd_event_socket_set fd_es_set = { 0, { 0 }, { NULL } };
WSAEVENT server_event = WSACreateEvent();
if (WSA_INVALID_EVENT == server_event)
{
printf("event_server error,error_code:%d\n", WSAGetLastError());
closesocket(socket_server);
WSACleanup();
return -1;
}
int res_server_event_select = WSAEventSelect(socket_server, server_event, FD_ACCEPT);
if (SOCKET_ERROR == res_server_event_select)
{
printf("server_event_select error,error_code:%d\n", WSAGetLastError());
BOOL colse_event_flag = WSACloseEvent(server_event);
if (TRUE == colse_event_flag)
{
printf("server_event close success\n");
}
else if (FALSE == colse_event_flag)
{
printf("server_event close failed,error_code:%d\n", WSAGetLastError());
}
closesocket(socket_server);
WSACleanup();
return -1;
}
fd_es_set.all_event[fd_es_set.count] = server_event;
fd_es_set.all_sock[fd_es_set.count] = socket_server;
fd_es_set.count++;
while (1)
{
DWORD res_wait = WSAWaitForMultipleEvents(fd_es_set.count,
fd_es_set.all_event,
FALSE,
120,
FALSE);
if (WSA_WAIT_FAILED == res_wait)
{
printf("WSAWaitForMultipleEvents error, error_code:%d\n", WSAGetLastError());
continue;
}
DWORD index = res_wait - WSA_WAIT_EVENT_0;
for (int i = index; i < fd_es_set.count; i++)
{
DWORD res_wait_event = WSAWaitForMultipleEvents(1,
&fd_es_set.all_event[i],
FALSE,
0,
FALSE);
if (WSA_WAIT_FAILED == res_wait_event)
{
printf("WSAWaitForMultipleEvents error, error_code:%d\n", WSAGetLastError());
continue;
}
if (WSA_WAIT_TIMEOUT == res_wait_event)
{
continue;
}
WSANETWORKEVENTS network_events;
int res_enum_events = WSAEnumNetworkEvents(fd_es_set.all_sock[i],
fd_es_set.all_event[i],
&network_events);
if (SOCKET_ERROR == res_enum_events)
{
printf("WSAEnumNetworkEvents error, error_code:%d\n", res_enum_events);
break;
}
if (network_events.lNetworkEvents & FD_ACCEPT)
{
if (0 == network_events.iErrorCode[FD_ACCEPT_BIT])
{
SOCKET socket_client = accept(fd_es_set.all_sock[i], NULL, NULL);
if (INVALID_SOCKET == socket_client)
{
continue;
}
WSAEVENT wsa_client_event = WSACreateEvent();
if (WSA_INVALID_EVENT == wsa_client_event)
{
closesocket(socket_client);
continue;
}
int res_client_event_select = WSAEventSelect(socket_client,
wsa_client_event,
FD_READ | FD_CLOSE | FD_WRITE);
if (SOCKET_ERROR == res_client_event_select)
{
printf("client_event_select error,error_code:%d\n", WSAGetLastError());
BOOL colse_event_flag = WSACloseEvent(wsa_client_event);
if (TRUE == colse_event_flag)
{
printf("wsa_client_event close success\n");
}
else if (FALSE == colse_event_flag)
{
printf("wsa_client_event close failed,error_code:%d\n", WSAGetLastError());
}
closesocket(socket_client);
WSACleanup();
return -1;
}
fd_es_set.all_sock[fd_es_set.count] = socket_client;
fd_es_set.all_event[fd_es_set.count] = wsa_client_event;
fd_es_set.count++;
printf("accept event\n");
}
else
{
printf("network_events FD_ACCEPT | socket error, error_code:%d\n",
network_events.iErrorCode[FD_ACCEPT_BIT]);
continue;
}
}
if (network_events.lNetworkEvents & FD_WRITE)
{
if (0 == network_events.iErrorCode[FD_WRITE_BIT])
{
int res_send = send(fd_es_set.all_sock[i], "connect success",
strlen("connect success"), 0);
if (SOCKET_ERROR == res_send)
{
printf("send error, error_code:%d\n", WSAGetLastError());
continue;
}
printf("write event\n");
}
else
{
printf("network_events FD_WRITE | socket error, error_code:%d\n",
network_events.iErrorCode[FD_WRITE_BIT]);
continue;
}
}
if (network_events.lNetworkEvents & FD_READ)
{
if (0 == network_events.iErrorCode[FD_READ_BIT])
{
char recv_buf[1500] = { 0 };
int res_recv = recv(fd_es_set.all_sock[i], recv_buf, 1499, 0);
if (SOCKET_ERROR == res_recv)
{
printf("recv error, error_code:%d\n", WSAGetLastError());
continue;
}
printf("recv data:%s\n", recv_buf);
}
else
{
printf("network_events FD_READ | socket error, error_code:%d\n",
network_events.iErrorCode[FD_READ_BIT]);
}
}
if (network_events.lNetworkEvents & FD_CLOSE)
{
printf("client close\n");
printf("network_events FD_CLOSE | socket error, error_code:%d\n",
network_events.iErrorCode[FD_CLOSE_BIT]);
closesocket(fd_es_set.all_sock[i]);
fd_es_set.all_sock[i] = fd_es_set.all_sock[fd_es_set.count - 1];
WSACloseEvent(fd_es_set.all_event[i]);
fd_es_set.all_event[i] = fd_es_set.all_event[fd_es_set.count - 1];
fd_es_set.count--;
}
}
}
BOOL colse_event_flag = WSACloseEvent(server_event);
if (TRUE == colse_event_flag)
{
printf("event_server close success\n");
}
else if (FALSE == colse_event_flag)
{
printf("event_server close failed,error_code:%d\n", WSAGetLastError());
}
closesocket(socket_server);
WSACleanup();
printf("\n");
system("pause");
return 0;
}
3.7 增加事件数量
(WSAWaitForMultipleEvents()函数调用一次)1组最大64个事件
3.7.1 一个一个的投递
event_select_server.c
#define _CRT_SECURE_NO_WARNINGS
#include <WinSock2.h>
#include <stdio.h>
#pragma comment(lib,"Ws2_32.lib")
typedef struct fd_event_socket_set
{
unsigned short count;
SOCKET all_sock[1024];
WSAEVENT all_event[1024];
};
fd_set fd_set_socks;
BOOL WINAPI fun(DWORD dw_ctrl_type)
{
switch (dw_ctrl_type)
{
case CTRL_CLOSE_EVENT:
{
{
}
}
break;
default:
break;
}
return TRUE;
}
int main(int argc, char* argv[])
{
SetConsoleCtrlHandler(fun, TRUE);
WORD ws_verson = MAKEWORD(2, 2);
WSADATA wd_sock_msg;
int ret = WSAStartup(ws_verson, &wd_sock_msg);
if (0 != ret)
{
switch (ret)
{
case WSASYSNOTREADY:
printf("重启下电脑试试,或者检查网络库!");
break;
case WSAVERNOTSUPPORTED:
printf("请更新网络库!");
break;
case WSAEPROCLIM:
printf("请重新启动!");
break;
case WSAEINPROGRESS:
printf("请尝试关掉不必要的软件,为当前网络运行提供充足资源!");
break;
case WSAEFAULT:
printf("参数错误!");
break;
default:
break;
}
return 0;
}
printf("网络库打开成功!\n");
if (2 != LOBYTE(wd_sock_msg.wVersion) ||
2 != HIBYTE(wd_sock_msg.wVersion))
{
WSACleanup();
return -1;
}
printf("网络库版本号:(%d,%d)\n", LOBYTE(wd_sock_msg.wVersion), HIBYTE(wd_sock_msg.wVersion));
SOCKET socket_server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (INVALID_SOCKET == socket_server)
{
printf("socket_server created failed,error_code:%d\n", WSAGetLastError());
WSACleanup();
return -1;
}
else
printf("socket_server created success,return code:%d\n", socket_server);
struct sockaddr_in si;
si.sin_family = AF_INET;
si.sin_port = htons(12345);
si.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
int res_bind = bind(socket_server, (const struct sockaddr *) &si, sizeof(si));
if (SOCKET_ERROR == res_bind)
{
printf("bind failed,error_code:%d\n", WSAGetLastError());
closesocket(socket_server);
WSACleanup();
return -1;
}
else
printf("bind success,return code:%d\n", res_bind);
int res_listen = listen(socket_server, SOMAXCONN);
if (SOCKET_ERROR == res_listen)
{
printf("listen failed,error_code:%d\n", WSAGetLastError());
closesocket(socket_server);
WSACleanup();
return -1;
}
else
printf("listen success,return code:%d\n", res_listen);
struct fd_event_socket_set fd_es_set = { 0, { 0 }, { NULL } };
WSAEVENT server_event = WSACreateEvent();
if (WSA_INVALID_EVENT == server_event)
{
printf("event_server error,error_code:%d\n", WSAGetLastError());
closesocket(socket_server);
WSACleanup();
return -1;
}
int res_server_event_select = WSAEventSelect(socket_server, server_event, FD_ACCEPT);
if (SOCKET_ERROR == res_server_event_select)
{
printf("server_event_select error,error_code:%d\n", WSAGetLastError());
BOOL colse_event_flag = WSACloseEvent(server_event);
if (TRUE == colse_event_flag)
{
printf("server_event close success\n");
}
else if (FALSE == colse_event_flag)
{
printf("server_event close failed,error_code:%d\n", WSAGetLastError());
}
closesocket(socket_server);
WSACleanup();
return -1;
}
fd_es_set.all_event[fd_es_set.count] = server_event;
fd_es_set.all_sock[fd_es_set.count] = socket_server;
fd_es_set.count++;
while (1)
{
for (int i = 0; i < fd_es_set.count; i++)
{
DWORD res_wait_event = WSAWaitForMultipleEvents(1,
&fd_es_set.all_event[i],
FALSE,
0,
FALSE);
if (WSA_WAIT_FAILED == res_wait_event)
{
printf("WSAWaitForMultipleEvents error, error_code:%d\n", WSAGetLastError());
continue;
}
if (WSA_WAIT_TIMEOUT == res_wait_event)
{
continue;
}
WSANETWORKEVENTS network_events;
int res_enum_events = WSAEnumNetworkEvents(fd_es_set.all_sock[i],
fd_es_set.all_event[i],
&network_events);
if (SOCKET_ERROR == res_enum_events)
{
printf("WSAEnumNetworkEvents error, error_code:%d\n", res_enum_events);
break;
}
if (network_events.lNetworkEvents & FD_ACCEPT)
{
if (0 == network_events.iErrorCode[FD_ACCEPT_BIT])
{
SOCKET socket_client = accept(fd_es_set.all_sock[i], NULL, NULL);
if (INVALID_SOCKET == socket_client)
{
continue;
}
WSAEVENT wsa_client_event = WSACreateEvent();
if (WSA_INVALID_EVENT == wsa_client_event)
{
closesocket(socket_client);
continue;
}
int res_client_event_select = WSAEventSelect(socket_client,
wsa_client_event,
FD_READ | FD_CLOSE | FD_WRITE);
if (SOCKET_ERROR == res_client_event_select)
{
printf("client_event_select error,error_code:%d\n", WSAGetLastError());
BOOL colse_event_flag = WSACloseEvent(wsa_client_event);
if (TRUE == colse_event_flag)
{
printf("wsa_client_event close success\n");
}
else if (FALSE == colse_event_flag)
{
printf("wsa_client_event close failed,error_code:%d\n", WSAGetLastError());
}
closesocket(socket_client);
WSACleanup();
return -1;
}
fd_es_set.all_sock[fd_es_set.count] = socket_client;
fd_es_set.all_event[fd_es_set.count] = wsa_client_event;
fd_es_set.count++;
printf("accept event\n");
}
else
{
printf("network_events FD_ACCEPT | socket error, error_code:%d\n",
network_events.iErrorCode[FD_ACCEPT_BIT]);
continue;
}
}
if (network_events.lNetworkEvents & FD_WRITE)
{
if (0 == network_events.iErrorCode[FD_WRITE_BIT])
{
int res_send = send(fd_es_set.all_sock[i], "connect success",
strlen("connect success"), 0);
if (SOCKET_ERROR == res_send)
{
printf("send error, error_code:%d\n", WSAGetLastError());
continue;
}
printf("write event\n");
}
else
{
printf("network_events FD_WRITE | socket error, error_code:%d\n",
network_events.iErrorCode[FD_WRITE_BIT]);
continue;
}
}
if (network_events.lNetworkEvents & FD_READ)
{
if (0 == network_events.iErrorCode[FD_READ_BIT])
{
char recv_buf[1500] = { 0 };
int res_recv = recv(fd_es_set.all_sock[i], recv_buf, 1499, 0);
if (SOCKET_ERROR == res_recv)
{
printf("recv error, error_code:%d\n", WSAGetLastError());
continue;
}
printf("recv data:%s\n", recv_buf);
}
else
{
printf("network_events FD_READ | socket error, error_code:%d\n",
network_events.iErrorCode[FD_READ_BIT]);
}
}
if (network_events.lNetworkEvents & FD_CLOSE)
{
printf("client close\n");
printf("network_events FD_CLOSE | socket error, error_code:%d\n",
network_events.iErrorCode[FD_CLOSE_BIT]);
closesocket(fd_es_set.all_sock[i]);
fd_es_set.all_sock[i] = fd_es_set.all_sock[fd_es_set.count - 1];
WSACloseEvent(fd_es_set.all_event[i]);
fd_es_set.all_event[i] = fd_es_set.all_event[fd_es_set.count - 1];
fd_es_set.count--;
}
}
}
BOOL colse_event_flag = WSACloseEvent(server_event);
if (TRUE == colse_event_flag)
{
printf("event_server close success\n");
}
else if (FALSE == colse_event_flag)
{
printf("event_server close failed,error_code:%d\n", WSAGetLastError());
}
closesocket(socket_server);
WSACleanup();
printf("\n");
system("pause");
return 0;
}
3.7.2 一组一组的投递
event_select_server.c
#define _CRT_SECURE_NO_WARNINGS
#include <WinSock2.h>
#include <stdio.h>
#pragma comment(lib,"Ws2_32.lib")
typedef struct fd_event_socket_set
{
unsigned short count;
SOCKET all_sock[WSA_MAXIMUM_WAIT_EVENTS];
WSAEVENT all_event[WSA_MAXIMUM_WAIT_EVENTS];
};
fd_set fd_set_socks;
BOOL WINAPI fun(DWORD dw_ctrl_type)
{
switch (dw_ctrl_type)
{
case CTRL_CLOSE_EVENT:
{
{
}
}
break;
default:
break;
}
return TRUE;
}
int main(int argc, char* argv[])
{
SetConsoleCtrlHandler(fun, TRUE);
WORD ws_verson = MAKEWORD(2, 2);
WSADATA wd_sock_msg;
int ret = WSAStartup(ws_verson, &wd_sock_msg);
if (0 != ret)
{
switch (ret)
{
case WSASYSNOTREADY:
printf("重启下电脑试试,或者检查网络库!");
break;
case WSAVERNOTSUPPORTED:
printf("请更新网络库!");
break;
case WSAEPROCLIM:
printf("请重新启动!");
break;
case WSAEINPROGRESS:
printf("请尝试关掉不必要的软件,为当前网络运行提供充足资源!");
break;
case WSAEFAULT:
printf("参数错误!");
break;
default:
break;
}
return 0;
}
printf("网络库打开成功!\n");
if (2 != LOBYTE(wd_sock_msg.wVersion) ||
2 != HIBYTE(wd_sock_msg.wVersion))
{
WSACleanup();
return -1;
}
printf("网络库版本号:(%d,%d)\n", LOBYTE(wd_sock_msg.wVersion), HIBYTE(wd_sock_msg.wVersion));
SOCKET socket_server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (INVALID_SOCKET == socket_server)
{
printf("socket_server created failed,error_code:%d\n", WSAGetLastError());
WSACleanup();
return -1;
}
else
printf("socket_server created success,return code:%d\n", socket_server);
struct sockaddr_in si;
si.sin_family = AF_INET;
si.sin_port = htons(12345);
si.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
int res_bind = bind(socket_server, (const struct sockaddr *) &si, sizeof(si));
if (SOCKET_ERROR == res_bind)
{
printf("bind failed,error_code:%d\n", WSAGetLastError());
closesocket(socket_server);
WSACleanup();
return -1;
}
else
printf("bind success,return code:%d\n", res_bind);
int res_listen = listen(socket_server, SOMAXCONN);
if (SOCKET_ERROR == res_listen)
{
printf("listen failed,error_code:%d\n", WSAGetLastError());
closesocket(socket_server);
WSACleanup();
return -1;
}
else
printf("listen success,return code:%d\n", res_listen);
struct fd_event_socket_set fd_es_set[20];
memset(fd_es_set, 0, sizeof(struct fd_event_socket_set)* 20);
WSAEVENT server_event = WSACreateEvent();
if (WSA_INVALID_EVENT == server_event)
{
printf("event_server error,error_code:%d\n", WSAGetLastError());
closesocket(socket_server);
WSACleanup();
return -1;
}
int res_server_event_select = WSAEventSelect(socket_server, server_event, FD_ACCEPT);
if (SOCKET_ERROR == res_server_event_select)
{
printf("server_event_select error,error_code:%d\n", WSAGetLastError());
BOOL colse_event_flag = WSACloseEvent(server_event);
if (TRUE == colse_event_flag)
{
printf("server_event close success\n");
}
else if (FALSE == colse_event_flag)
{
printf("server_event close failed,error_code:%d\n", WSAGetLastError());
}
closesocket(socket_server);
WSACleanup();
return -1;
}
fd_es_set[0].all_event[fd_es_set[0].count] = server_event;
fd_es_set[0].all_sock[fd_es_set[0].count] = socket_server;
fd_es_set[0].count++;
while (1)
{
for (int j = 0; j < 20; j++)
{
if (0 == fd_es_set[j].count)
{
continue;
}
DWORD res_wait = WSAWaitForMultipleEvents(fd_es_set[j].count,
fd_es_set[j].all_event,
FALSE,
0,
FALSE);
if (WSA_WAIT_FAILED == res_wait)
{
printf("WSAWaitForMultipleEvents error, error_code:%d\n", WSAGetLastError());
continue;
}
if (WSA_WAIT_TIMEOUT == res_wait)
{
continue;
}
DWORD index = res_wait - WSA_WAIT_EVENT_0;
for (int i = index; i < fd_es_set[j].count; i++)
{
DWORD res_wait_event = WSAWaitForMultipleEvents(1,
&fd_es_set[j].all_event[i],
FALSE,
0,
FALSE);
if (WSA_WAIT_FAILED == res_wait_event)
{
printf("WSAWaitForMultipleEvents error, error_code:%d\n", WSAGetLastError());
continue;
}
if (WSA_WAIT_TIMEOUT == res_wait_event)
{
continue;
}
WSANETWORKEVENTS network_events;
int res_enum_events = WSAEnumNetworkEvents(fd_es_set[j].all_sock[i],
fd_es_set[j].all_event[i],
&network_events);
if (SOCKET_ERROR == res_enum_events)
{
printf("WSAEnumNetworkEvents error, error_code:%d\n", res_enum_events);
break;
}
if (network_events.lNetworkEvents & FD_ACCEPT)
{
if (0 == network_events.iErrorCode[FD_ACCEPT_BIT])
{
SOCKET socket_client = accept(fd_es_set[j].all_sock[i], NULL, NULL);
if (INVALID_SOCKET == socket_client)
{
continue;
}
WSAEVENT wsa_client_event = WSACreateEvent();
if (WSA_INVALID_EVENT == wsa_client_event)
{
closesocket(socket_client);
continue;
}
int res_client_event_select = WSAEventSelect(socket_client,
wsa_client_event,
FD_READ | FD_CLOSE | FD_WRITE);
if (SOCKET_ERROR == res_client_event_select)
{
printf("client_event_select error,error_code:%d\n", WSAGetLastError());
BOOL colse_event_flag = WSACloseEvent(wsa_client_event);
if (TRUE == colse_event_flag)
{
printf("wsa_client_event close success\n");
}
else if (FALSE == colse_event_flag)
{
printf("wsa_client_event close failed,error_code:%d\n", WSAGetLastError());
}
closesocket(socket_client);
WSACleanup();
return -1;
}
for (int k = 0; k < 20; k++)
{
if (fd_es_set[k].count < 64)
{
fd_es_set[k].all_sock[fd_es_set[k].count] = socket_client;
fd_es_set[k].all_event[fd_es_set[k].count] = wsa_client_event;
fd_es_set[k].count++;
break;
}
}
printf("accept event\n");
}
else
{
printf("network_events FD_ACCEPT | socket error, error_code:%d\n",
network_events.iErrorCode[FD_ACCEPT_BIT]);
continue;
}
}
if (network_events.lNetworkEvents & FD_WRITE)
{
if (0 == network_events.iErrorCode[FD_WRITE_BIT])
{
int res_send = send(fd_es_set[j].all_sock[i], "connect success",
strlen("connect success"), 0);
if (SOCKET_ERROR == res_send)
{
printf("send error, error_code:%d\n", WSAGetLastError());
continue;
}
printf("write event\n");
}
else
{
printf("network_events FD_WRITE | socket error, error_code:%d\n",
network_events.iErrorCode[FD_WRITE_BIT]);
continue;
}
}
if (network_events.lNetworkEvents & FD_READ)
{
if (0 == network_events.iErrorCode[FD_READ_BIT])
{
char recv_buf[1500] = { 0 };
int res_recv = recv(fd_es_set[j].all_sock[i], recv_buf, 1499, 0);
if (SOCKET_ERROR == res_recv)
{
printf("recv error, error_code:%d\n", WSAGetLastError());
continue;
}
printf("recv data:%s\n", recv_buf);
}
else
{
printf("network_events FD_READ | socket error, error_code:%d\n",
network_events.iErrorCode[FD_READ_BIT]);
}
}
if (network_events.lNetworkEvents & FD_CLOSE)
{
printf("client close\n");
printf("network_events FD_CLOSE | socket error, error_code:%d\n",
network_events.iErrorCode[FD_CLOSE_BIT]);
closesocket(fd_es_set[j].all_sock[i]);
fd_es_set[j].all_sock[i] = fd_es_set[j].all_sock[fd_es_set[j].count - 1];
WSACloseEvent(fd_es_set[j].all_event[i]);
fd_es_set[j].all_event[i] = fd_es_set[j].all_event[fd_es_set[j].count - 1];
fd_es_set[j].count--;
}
}
}
}
BOOL colse_event_flag = WSACloseEvent(server_event);
if (TRUE == colse_event_flag)
{
printf("event_server close success\n");
}
else if (FALSE == colse_event_flag)
{
printf("event_server close failed,error_code:%d\n", WSAGetLastError());
}
closesocket(socket_server);
WSACleanup();
printf("\n");
system("pause");
return 0;
}
3.8 释放
3.8.1 优化前
#define _CRT_SECURE_NO_WARNINGS
#include <WinSock2.h>
#include <stdio.h>
#pragma comment(lib,"Ws2_32.lib")
typedef struct fd_event_socket_set
{
unsigned short count;
SOCKET all_sock[WSA_MAXIMUM_WAIT_EVENTS];
WSAEVENT all_event[WSA_MAXIMUM_WAIT_EVENTS];
};
fd_set fd_set_socks;
struct fd_event_socket_set fd_es_set = { 0, { 0 }, { NULL } };
BOOL WINAPI fun(DWORD dw_ctrl_type)
{
switch (dw_ctrl_type)
{
case CTRL_CLOSE_EVENT:
{
{
for (int i = 0; i < fd_es_set.count; i++)
{
closesocket(fd_es_set.all_sock[i]);
WSACloseEvent(fd_es_set.all_event[i]);
}
}
}
break;
default:
break;
}
return TRUE;
}
int main(int argc, char* argv[])
{
SetConsoleCtrlHandler(fun, TRUE);
WORD ws_verson = MAKEWORD(2, 2);
WSADATA wd_sock_msg;
int ret = WSAStartup(ws_verson, &wd_sock_msg);
if (0 != ret)
{
switch (ret)
{
case WSASYSNOTREADY:
printf("重启下电脑试试,或者检查网络库!");
break;
case WSAVERNOTSUPPORTED:
printf("请更新网络库!");
break;
case WSAEPROCLIM:
printf("请重新启动!");
break;
case WSAEINPROGRESS:
printf("请尝试关掉不必要的软件,为当前网络运行提供充足资源!");
break;
case WSAEFAULT:
printf("参数错误!");
break;
default:
break;
}
return 0;
}
printf("网络库打开成功!\n");
if (2 != LOBYTE(wd_sock_msg.wVersion) ||
2 != HIBYTE(wd_sock_msg.wVersion))
{
WSACleanup();
return -1;
}
printf("网络库版本号:(%d,%d)\n", LOBYTE(wd_sock_msg.wVersion), HIBYTE(wd_sock_msg.wVersion));
SOCKET socket_server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (INVALID_SOCKET == socket_server)
{
printf("socket_server created failed,error_code:%d\n", WSAGetLastError());
WSACleanup();
return -1;
}
else
printf("socket_server created success,return code:%d\n", socket_server);
struct sockaddr_in si;
si.sin_family = AF_INET;
si.sin_port = htons(12345);
si.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
int res_bind = bind(socket_server, (const struct sockaddr *) &si, sizeof(si));
if (SOCKET_ERROR == res_bind)
{
printf("bind failed,error_code:%d\n", WSAGetLastError());
closesocket(socket_server);
WSACleanup();
return -1;
}
else
printf("bind success,return code:%d\n", res_bind);
int res_listen = listen(socket_server, SOMAXCONN);
if (SOCKET_ERROR == res_listen)
{
printf("listen failed,error_code:%d\n", WSAGetLastError());
closesocket(socket_server);
WSACleanup();
return -1;
}
else
printf("listen success,return code:%d\n", res_listen);
WSAEVENT server_event = WSACreateEvent();
if (WSA_INVALID_EVENT == server_event)
{
printf("event_server error,error_code:%d\n", WSAGetLastError());
closesocket(socket_server);
WSACleanup();
return -1;
}
int res_server_event_select = WSAEventSelect(socket_server, server_event, FD_ACCEPT);
if (SOCKET_ERROR == res_server_event_select)
{
printf("server_event_select error,error_code:%d\n", WSAGetLastError());
BOOL colse_event_flag = WSACloseEvent(server_event);
if (TRUE == colse_event_flag)
{
printf("server_event close success\n");
}
else if (FALSE == colse_event_flag)
{
printf("server_event close failed,error_code:%d\n", WSAGetLastError());
}
closesocket(socket_server);
WSACleanup();
return -1;
}
fd_es_set.all_event[fd_es_set.count] = server_event;
fd_es_set.all_sock[fd_es_set.count] = socket_server;
fd_es_set.count++;
while (1)
{
DWORD res_wait_event = WSAWaitForMultipleEvents(fd_es_set.count,
fd_es_set.all_event,
FALSE,
WSA_INFINITE ,
FALSE);
if (WSA_WAIT_FAILED == res_wait_event)
{
printf("WSAWaitForMultipleEvents error, error_code:%d\n", WSAGetLastError());
break;
}
DWORD index = res_wait_event - WSA_WAIT_EVENT_0;
WSANETWORKEVENTS network_events;
int res_enum_events = WSAEnumNetworkEvents(fd_es_set.all_sock[index],
fd_es_set.all_event[index],
&network_events);
if (SOCKET_ERROR == res_enum_events)
{
printf("WSAEnumNetworkEvents error, error_code:%d\n", res_enum_events);
break;
}
if (network_events.lNetworkEvents & FD_ACCEPT)
{
if (0 == network_events.iErrorCode[FD_ACCEPT_BIT])
{
SOCKET socket_client = accept(fd_es_set.all_sock[index], NULL, NULL);
if (INVALID_SOCKET == socket_client)
{
continue;
}
WSAEVENT wsa_client_event = WSACreateEvent();
if (WSA_INVALID_EVENT == wsa_client_event)
{
closesocket(socket_client);
continue;
}
int res_client_event_select = WSAEventSelect(socket_client,
wsa_client_event,
FD_READ | FD_CLOSE | FD_WRITE);
if (SOCKET_ERROR == res_client_event_select)
{
printf("client_event_select error,error_code:%d\n", WSAGetLastError());
BOOL colse_event_flag = WSACloseEvent(wsa_client_event);
if (TRUE == colse_event_flag)
{
printf("wsa_client_event close success\n");
}
else if (FALSE == colse_event_flag)
{
printf("wsa_client_event close failed,error_code:%d\n", WSAGetLastError());
}
closesocket(socket_client);
WSACleanup();
return -1;
}
fd_es_set.all_sock[fd_es_set.count] = socket_client;
fd_es_set.all_event[fd_es_set.count] = wsa_client_event;
fd_es_set.count++;
printf("accept event\n");
}
else
{
printf("network_events FD_ACCEPT | socket error, error_code:%d\n",
network_events.iErrorCode[FD_ACCEPT_BIT]);
continue;
}
}
if (network_events.lNetworkEvents & FD_WRITE)
{
if (0 == network_events.iErrorCode[FD_WRITE_BIT])
{
int res_send = send(fd_es_set.all_sock[index], "connect success",
strlen("connect success"), 0);
if (SOCKET_ERROR == res_send)
{
printf("send error, error_code:%d\n", WSAGetLastError());
continue;
}
printf("write event\n");
}
else
{
printf("network_events FD_WRITE | socket error, error_code:%d\n",
network_events.iErrorCode[FD_WRITE_BIT]);
continue;
}
}
if (network_events.lNetworkEvents & FD_READ)
{
if (0 == network_events.iErrorCode[FD_READ_BIT])
{
char recv_buf[1500] = { 0 };
int res_recv = recv(fd_es_set.all_sock[index], recv_buf, 1499, 0);
if (SOCKET_ERROR == res_recv)
{
printf("recv error, error_code:%d\n", WSAGetLastError());
continue;
}
printf("recv data:%s\n", recv_buf);
}
else
{
printf("network_events FD_READ | socket error, error_code:%d\n",
network_events.iErrorCode[FD_READ_BIT]);
}
}
if (network_events.lNetworkEvents & FD_CLOSE)
{
printf("client close\n");
printf("network_events FD_CLOSE | socket error, error_code:%d\n",
network_events.iErrorCode[FD_CLOSE_BIT]);
closesocket(fd_es_set.all_sock[index]);
fd_es_set.all_sock[index] = fd_es_set.all_sock[fd_es_set.count - 1];
WSACloseEvent(fd_es_set.all_event[index]);
fd_es_set.all_event[index] = fd_es_set.all_event[fd_es_set.count - 1];
fd_es_set.count--;
}
}
for (int i = 0; i < fd_es_set.count; i++)
{
closesocket(fd_es_set.all_sock[i]);
WSACloseEvent(fd_es_set.all_event[i]);
}
BOOL colse_event_flag = WSACloseEvent(server_event);
if (TRUE == colse_event_flag)
{
printf("event_server close success\n");
}
else if (FALSE == colse_event_flag)
{
printf("event_server close failed,error_code:%d\n", WSAGetLastError());
}
closesocket(socket_server);
WSACleanup();
printf("\n");
system("pause");
return 0;
}
3.8.2 一组一组
#define _CRT_SECURE_NO_WARNINGS
#include <WinSock2.h>
#include <stdio.h>
#pragma comment(lib,"Ws2_32.lib")
typedef struct fd_event_socket_set
{
unsigned short count;
SOCKET all_sock[WSA_MAXIMUM_WAIT_EVENTS];
WSAEVENT all_event[WSA_MAXIMUM_WAIT_EVENTS];
};
fd_set fd_set_socks;
struct fd_event_socket_set fd_es_set[20];
BOOL WINAPI fun(DWORD dw_ctrl_type)
{
switch (dw_ctrl_type)
{
case CTRL_CLOSE_EVENT:
{
{
for (int j = 0; j < 20;j++)
{
for (int i = 0; i < fd_es_set[j].count; i++)
{
closesocket(fd_es_set[j].all_sock[i]);
WSACloseEvent(fd_es_set[j].all_event[i]);
}
}
}
}
break;
default:
break;
}
return TRUE;
}
int main(int argc, char* argv[])
{
SetConsoleCtrlHandler(fun, TRUE);
WORD ws_verson = MAKEWORD(2, 2);
WSADATA wd_sock_msg;
int ret = WSAStartup(ws_verson, &wd_sock_msg);
if (0 != ret)
{
switch (ret)
{
case WSASYSNOTREADY:
printf("重启下电脑试试,或者检查网络库!");
break;
case WSAVERNOTSUPPORTED:
printf("请更新网络库!");
break;
case WSAEPROCLIM:
printf("请重新启动!");
break;
case WSAEINPROGRESS:
printf("请尝试关掉不必要的软件,为当前网络运行提供充足资源!");
break;
case WSAEFAULT:
printf("参数错误!");
break;
default:
break;
}
return 0;
}
printf("网络库打开成功!\n");
if (2 != LOBYTE(wd_sock_msg.wVersion) ||
2 != HIBYTE(wd_sock_msg.wVersion))
{
WSACleanup();
return -1;
}
printf("网络库版本号:(%d,%d)\n", LOBYTE(wd_sock_msg.wVersion), HIBYTE(wd_sock_msg.wVersion));
SOCKET socket_server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (INVALID_SOCKET == socket_server)
{
printf("socket_server created failed,error_code:%d\n", WSAGetLastError());
WSACleanup();
return -1;
}
else
printf("socket_server created success,return code:%d\n", socket_server);
struct sockaddr_in si;
si.sin_family = AF_INET;
si.sin_port = htons(12345);
si.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
int res_bind = bind(socket_server, (const struct sockaddr *) &si, sizeof(si));
if (SOCKET_ERROR == res_bind)
{
printf("bind failed,error_code:%d\n", WSAGetLastError());
closesocket(socket_server);
WSACleanup();
return -1;
}
else
printf("bind success,return code:%d\n", res_bind);
int res_listen = listen(socket_server, SOMAXCONN);
if (SOCKET_ERROR == res_listen)
{
printf("listen failed,error_code:%d\n", WSAGetLastError());
closesocket(socket_server);
WSACleanup();
return -1;
}
else
printf("listen success,return code:%d\n", res_listen);
WSAEVENT server_event = WSACreateEvent();
if (WSA_INVALID_EVENT == server_event)
{
printf("event_server error,error_code:%d\n", WSAGetLastError());
closesocket(socket_server);
WSACleanup();
return -1;
}
int res_server_event_select = WSAEventSelect(socket_server, server_event, FD_ACCEPT);
if (SOCKET_ERROR == res_server_event_select)
{
printf("server_event_select error,error_code:%d\n", WSAGetLastError());
BOOL colse_event_flag = WSACloseEvent(server_event);
if (TRUE == colse_event_flag)
{
printf("server_event close success\n");
}
else if (FALSE == colse_event_flag)
{
printf("server_event close failed,error_code:%d\n", WSAGetLastError());
}
closesocket(socket_server);
WSACleanup();
return -1;
}
fd_es_set[0].all_event[fd_es_set[0].count] = server_event;
fd_es_set[0].all_sock[fd_es_set[0].count] = socket_server;
fd_es_set[0].count++;
while (1)
{
for (int j = 0; j < 20; j++)
{
if (0 == fd_es_set[j].count)
{
continue;
}
DWORD res_wait = WSAWaitForMultipleEvents(fd_es_set[j].count,
fd_es_set[j].all_event,
FALSE,
0,
FALSE);
if (WSA_WAIT_FAILED == res_wait)
{
printf("WSAWaitForMultipleEvents error, error_code:%d\n", WSAGetLastError());
continue;
}
if (WSA_WAIT_TIMEOUT == res_wait)
{
continue;
}
DWORD index = res_wait - WSA_WAIT_EVENT_0;
for (int i = index; i < fd_es_set[j].count; i++)
{
DWORD res_wait_event = WSAWaitForMultipleEvents(1,
&fd_es_set[j].all_event[i],
FALSE,
0,
FALSE);
if (WSA_WAIT_FAILED == res_wait_event)
{
printf("WSAWaitForMultipleEvents error, error_code:%d\n", WSAGetLastError());
continue;
}
if (WSA_WAIT_TIMEOUT == res_wait_event)
{
continue;
}
WSANETWORKEVENTS network_events;
int res_enum_events = WSAEnumNetworkEvents(fd_es_set[j].all_sock[i],
fd_es_set[j].all_event[i],
&network_events);
if (SOCKET_ERROR == res_enum_events)
{
printf("WSAEnumNetworkEvents error, error_code:%d\n", res_enum_events);
break;
}
if (network_events.lNetworkEvents & FD_ACCEPT)
{
if (0 == network_events.iErrorCode[FD_ACCEPT_BIT])
{
SOCKET socket_client = accept(fd_es_set[j].all_sock[i], NULL, NULL);
if (INVALID_SOCKET == socket_client)
{
continue;
}
WSAEVENT wsa_client_event = WSACreateEvent();
if (WSA_INVALID_EVENT == wsa_client_event)
{
closesocket(socket_client);
continue;
}
int res_client_event_select = WSAEventSelect(socket_client,
wsa_client_event,
FD_READ | FD_CLOSE | FD_WRITE);
if (SOCKET_ERROR == res_client_event_select)
{
printf("client_event_select error,error_code:%d\n", WSAGetLastError());
BOOL colse_event_flag = WSACloseEvent(wsa_client_event);
if (TRUE == colse_event_flag)
{
printf("wsa_client_event close success\n");
}
else if (FALSE == colse_event_flag)
{
printf("wsa_client_event close failed,error_code:%d\n", WSAGetLastError());
}
closesocket(socket_client);
WSACleanup();
return -1;
}
for (int k = 0; k < 20; k++)
{
if (fd_es_set[k].count < 64)
{
fd_es_set[k].all_sock[fd_es_set[k].count] = socket_client;
fd_es_set[k].all_event[fd_es_set[k].count] = wsa_client_event;
fd_es_set[k].count++;
break;
}
}
printf("accept event\n");
}
else
{
printf("network_events FD_ACCEPT | socket error, error_code:%d\n",
network_events.iErrorCode[FD_ACCEPT_BIT]);
continue;
}
}
if (network_events.lNetworkEvents & FD_WRITE)
{
if (0 == network_events.iErrorCode[FD_WRITE_BIT])
{
int res_send = send(fd_es_set[j].all_sock[i], "connect success",
strlen("connect success"), 0);
if (SOCKET_ERROR == res_send)
{
printf("send error, error_code:%d\n", WSAGetLastError());
continue;
}
printf("write event\n");
}
else
{
printf("network_events FD_WRITE | socket error, error_code:%d\n",
network_events.iErrorCode[FD_WRITE_BIT]);
continue;
}
}
if (network_events.lNetworkEvents & FD_READ)
{
if (0 == network_events.iErrorCode[FD_READ_BIT])
{
char recv_buf[1500] = { 0 };
int res_recv = recv(fd_es_set[j].all_sock[i], recv_buf, 1499, 0);
if (SOCKET_ERROR == res_recv)
{
printf("recv error, error_code:%d\n", WSAGetLastError());
continue;
}
printf("recv data:%s\n", recv_buf);
}
else
{
printf("network_events FD_READ | socket error, error_code:%d\n",
network_events.iErrorCode[FD_READ_BIT]);
}
}
if (network_events.lNetworkEvents & FD_CLOSE)
{
printf("client close\n");
printf("network_events FD_CLOSE | socket error, error_code:%d\n",
network_events.iErrorCode[FD_CLOSE_BIT]);
closesocket(fd_es_set[j].all_sock[i]);
fd_es_set[j].all_sock[i] = fd_es_set[j].all_sock[fd_es_set[j].count - 1];
WSACloseEvent(fd_es_set[j].all_event[i]);
fd_es_set[j].all_event[i] = fd_es_set[j].all_event[fd_es_set[j].count - 1];
fd_es_set[j].count--;
}
}
}
}
for (int j = 0; j < 20; j++)
{
for (int i = 0; i < fd_es_set[j].count; i++)
{
closesocket(fd_es_set[j].all_sock[i]);
WSACloseEvent(fd_es_set[j].all_event[i]);
}
}
WSACleanup();
printf("\n");
system("pause");
return 0;
}
select模型服务端DEMO
4 select模型与event_select模型比较
|