CSDN居然可以上传附件哪,方便多了
请教大家一个问题,为什么我的IOCP服务器总是慢一拍
比如客户端连接时该收到OP_ACCEPT的时候,没反应(其实已经连接上了)
然后客户端发消息,才显示OP_ACCEPT消息,奇了大怪了:(
哪位高手帮我看看代码谢谢了:)
请教大家一个问题,为什么我的IOCP服务器总是慢一拍
比如客户端连接时该收到OP_ACCEPT的时候,没反应(其实已经连接上了)
然后客户端发消息,才显示OP_ACCEPT消息,奇了大怪了:(
哪位高手帮我看看代码谢谢了:)
解决方案 »
- 动态创建Tab标签
- 请问MENU自绘菜单为什么无法自绘Menu Bar
- 缩略图的问题
- 用InstallShield打包后的安装包运行提示一个_desktop.ini文件访问错误。
- 大牛们帮忙给解答一下,UDP发送之后为什么select会出现假可读?
- ●●●●●VC+ADO 用SQL怎样实现“与”的功能●●●●●
- 为什么编译的可执行文件在其他计算机无法运行?
- 哪位仁兄帮我解约用CreateBitmap(....)创建位图,很急
- ini文件操作问题
- 常常看到报纸、杂志这个认证,哪个认证的,谁知道为什么要认证?搞vc也要认证么?
- 高手帮忙:MFC实现IIS5.0创建虚拟根目录
- 大家给点建议,来者有分(分不够可加,自己只能给到100),只希望得到大家的帮助.....T_T
BOOL b = m_lpfnAcceptEx(m_sListen,
pBuffer->sClient,
pBuffer->buff,
pBuffer->nLen - ((sizeof(sockaddr_in) + 16) * 2),//请注意这个参数的值
sizeof(sockaddr_in) + 16,
sizeof(sockaddr_in) + 16,
&dwBytes,
&pBuffer->ol);看看MSDN当中的说明
BOOL AcceptEx(
__in SOCKET sListenSocket,
__in SOCKET sAcceptSocket,
__in PVOID lpOutputBuffer,
__in DWORD dwReceiveDataLength,
__in DWORD dwLocalAddressLength,
__in DWORD dwRemoteAddressLength,
__out LPDWORD lpdwBytesReceived,
__in LPOVERLAPPED lpOverlapped
);Parameters
sListenSocket
A descriptor identifying a socket that has already been called with the listen function. A server application waits for attempts to connect on this socket.sAcceptSocket
A descriptor identifying a socket on which to accept an incoming connection. This socket must not be bound or connected.lpOutputBuffer
A pointer to a buffer that receives the first block of data sent on a new connection, the local address of the server, and the remote address of the client. The receive data is written to the first part of the buffer starting at offset zero, while the addresses are written to the latter part of the buffer. This parameter must be specified.dwReceiveDataLength
The number of bytes in lpOutputBuffer that will be used for actual receive data at the beginning of the buffer. This size should not include the size of the local address of the server, nor the remote address of the client; they are appended to the output buffer. If dwReceiveDataLength is zero, accepting the connection will not result in a receive operation. Instead, AcceptEx completes as soon as a connection arrives, without waiting for any data.dwLocalAddressLength
The number of bytes reserved for the local address information. This value must be at least 16 bytes more than the maximum address length for the transport protocol in use.dwRemoteAddressLength
The number of bytes reserved for the remote address information. This value must be at least 16 bytes more than the maximum address length for the transport protocol in use. Cannot be zero.lpdwBytesReceived
A pointer to a DWORD that receives the count of bytes received. This parameter is set only if the operation completes synchronously. If it returns ERROR_IO_PENDING and is completed later, then this DWORD is never set and you must obtain the number of bytes read from the completion notification mechanism.lpOverlapped
An OVERLAPPED structure that is used to process the request. This parameter must be specified; it cannot be NULL.
你可以通过一次调用就完成接受客户端连接请求和接受数据(通过传送lpOutputBuffer参数)两件事情。
也就是说,如果客户端在发出连接的同时传输数据,
你的AcceptEx()调用在连接创建并接收了客户端数据后就可以立刻返回。
这样可能是很有用的,但是也可能会引发问题,因为AcceptEx()必须等全部客户端数据都收到了才返回。
具体来说,如果你在发出AcceptEx()调用的同时传递了 lpOutputBuffer参数,那么AcceptEx()不再是一项原子型的操作,
而是分成了两步:接受客户连接,等待接收数据。当缺少一种机制来通知你的应用程序所发生的这种情况:“连接已经建立了,正在等待客户端数据”,这将意味着有可能出现客户端只发出连接请求,但是不发送数据。如果你的服务器收到太多这种类型的连接时,它将拒绝连接更多的合法客户端请求。这就是黑客进行“拒绝服务”攻击的常见手法。
__in PVOID lpOutputBuffer,
也应该设置成NULL。调试的结果是ACCEPT同时SOCKET也关闭了。
__in PVOID lpOutputBuffer, <---NULL
__in DWORD dwReceiveDataLength, <---02)接收到一个shutdown的ACCEPT请求
__in DWORD dwReceiveDataLength, <---0我使用127.0.0.1做的测试,
不知道用另外一台机子connect是什么情况。
if(pBuffer->nOperation == OP_ACCEPT)
{
if(dwTrans == 0)
{
setsockopt (pBuffer->sClient,
SOL_SOCKET,
SO_UPDATE_ACCEPT_CONTEXT,
(char *)&(pBuffer->sClient),
sizeof (pBuffer->sClient));
sockaddr_in addr;
int nlen;
getpeername (pBuffer->sClient, (sockaddr*)pRemoteAddr,&nlen);
printf("addr=%s",inet_ntoa(addr.sin_addr) );
这个时候的dwTrans为0的判断没有意义。
换这个方式可以取到IP地址,但不是127.0.0.1
===============
是否127.0.0.1,关键要看客户端连入时选择的是什么地址。就算是本机,如果连入时使用的不是127.0.0.1,那么得到的就不会是127.0.0.1,具体可以通过netstat看得到。如果取得的结果有异议,那么就有可能取错了。