请僵哥等高手解答IOCP优化难点?
小弟不才,请CSDN大牛解决IOCP优化问题:
proxy server构架:
a)转发服务端s1采用IOCPx3模式:针对客户端c的收发包,使用IOCP-1;针对其他服务端s2的收发包,使用IOCP-2;业务层逻辑包通过IOCP-3转发到1或者2;
b)网络层(IOCP-1/2)只负责收发包,收到包后投递到IOCP-3,然后视业务逻辑分别转发给IOCP-2或1,处理或再投递;
c)为防止大量非分页内存锁定:WSASend已做队列缓冲;WSARecv在连接进来后,投递0字节WSABUF。
问题来了:
问题一:在监听线程接收连接后,分配上下文并投递0字节缓冲区的WSARecv,已经实现高并发大吞吐量数据的接收没有问题,由于投递0字节WSARecv解锁,所以非分页内存有升也有降很正常。
但是在GCQS接收大量并发数据时,如果s1使用shutdown+closesocket主动断开某个连接字(比如恶意发包攻击等),GCQS有可能接收不到该IO正常返回(正常的话在该套接字上投递的0字节WSARecv会返回),因此此时无法正常回收context,在cmd里面netstat -ano -p tcp,确定该连接已经被关闭,只是GCQS无返回。
我现在是这样处理的:投递0字节WSARecv,如果该连接上有包发过来,那么GCQS正常返回,然后再投递一分页4096字节的缓冲区WSARecv,然后GCQS再次返回,这时ioSize已经包含实际数据长度了,我粘包处理完后,继续投递0字节WSARecv如此循环。
问题二:另外看网上有另外一种方法:投递0字节WSARecv,有包过来,GCQS会返回,然后通过循环recv接收,直到recv返回-1,WSAGetLastError==WSAEWOULDBLOCK
实际测试中发现,因为默认套接字是阻塞的,所以recv接收完数据后,会阻塞,并不会出现WSAEWOULDBLOCK的情况,所以无法正常跳出。是否需要在recv()之前将套接字先设置为异步的?等出现WSAEWOULDBLOCK跳出后,再设置成同步的?