服务器端,在WSAEventSelect模型下,怎么判断收到的FD_READ来自哪一个客户SOCKET

服务器端,在WSAEventSelect模型下,如何判断收到的FD_READ来自哪一个客户SOCKET?

我写了一个服务器,因为要用Openssl,所以不能用OverlappedIO,现在有一个问题,就是   在WSAEventSelect模型下,如何判断收到的FD_READ来自哪一个客户SOCKET?

------解决方案--------------------
WSAWaitForMultipleEvents
------解决方案--------------------
TCP客户端用WSAWaitForMultipleEvents等待所有数据连接的FD_READ、FD_CLOSE

TCP服务器端用WSAWaitForMultipleEvents等待监听的FD_ACCEPT和数据连接的FD_READ、FD_CLOSE

不管是客户端还是服务器端,每建立一个SOCKET就WSACreateEvent一个EVENT并WSAEventSelect,在WSAWaitForMultipleEvents里面等这些EVENT,EVENT与SOCKET一一对应,更具WSAWaitForMultipleEvents的返回值来确定是哪个SOCKET
------解决方案--------------------
你要支持更多的客户端就用完成端口。。

------解决方案--------------------
WSAWaitForMultipleEvents对每64个Event分组进行查询的方式达到支持> 64客户端的支持
缺点就是效率比完成端口低

下面是我改写的一个兼容WSAWaitForMultipleEvents函数,缺点是效率比完成端口低,优点是旧程序无需改动就可支持> 64的客户端

DWORD WSAWaitForMultipleEvents_Patch(DWORD cEvents,
const WSAEVENT FAR * lphEvents,
BOOL fWaitAll,
DWORD dwTimeout,
BOOL fAlertable
)
{
if(cEvents <= WSA_MAXIMUM_WAIT_EVENTS)
{
return WSAWaitForMultipleEvents(
cEvents,
lphEvents,
FALSE,
dwTimeout,
FALSE);
}
else
{
DWORD dwStatus;
DWORD cEventsX = cEvents; // 剩余信号量数目

DWORD segs = (cEvents + WSA_MAXIMUM_WAIT_EVENTS - 1) / WSA_MAXIMUM_WAIT_EVENTS; // 段数
DWORD timeout = dwTimeout / segs; // 每段等待时间

for(; cEventsX > 0;)
{
if(cEventsX < WSA_MAXIMUM_WAIT_EVENTS)
{
cEventsX = WSA_MAXIMUM_WAIT_EVENTS;
}

dwStatus = WSAWaitForMultipleEvents(
WSA_MAXIMUM_WAIT_EVENTS,
lphEvents + (cEvents - cEventsX),
FALSE,
timeout,
FALSE);

if(dwStatus > = WSA_WAIT_EVENT_0 && dwStatus < WSA_WAIT_EVENT_0 + WSA_MAXIMUM_WAIT_EVENTS)
return dwStatus + (cEvents - cEventsX);
else if(timeout != WSA_WAIT_TIMEOUT)
return dwStatus;

cEventsX -= WSA_MAXIMUM_WAIT_EVENTS;
}

return WSA_WAIT_TIMEOUT;
}
}

------解决方案--------------------
奇怪的问题。。。为啥不能用overlapped结构?wsarecv和wsasend又为什么不让用?
------解决方案--------------------
楼主看过设计模式的书没有?其中的命令模型可能对你有帮助,

比如,你可以把socket设成堵塞模式,把send or recv操作及他们操作的数据封装到一个对象,然后queue到你设计的线程池中序列化执行,记住这个线程池最好有个监控线程,就是当任务忙时多开线程,当任务减少时销毁线程,其中每个工作线程从任务队列中取任务,最后就是send and recv操作完成,怎么通知的问题,这个可以调用回调函数,当网络操作执行完成后,回调函数就把send or recv操作对象作为context参数进行调用,你在回调函数中可以对context判断就知道哪个操作完成了。当回调执行完成,再去取其他的任务。
麻烦是麻烦点,但是这样,能解决你很多异步调用模型。
------解决方案--------------------
为什么不用WSAAsyncSelect?