CSDN居然可以上传附件哪,方便多了
请教大家一个问题,为什么我的IOCP服务器总是慢一拍
比如客户端连接时该收到OP_ACCEPT的时候,没反应(其实已经连接上了)
然后客户端发消息,才显示OP_ACCEPT消息,奇了大怪了:(
哪位高手帮我看看代码谢谢了:)

解决方案 »

  1.   


    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.
      

  2.   

    意思也就是,如果你想它连接上就立即提示连接完成,则只须将dwReceiveDataLength赋0就OK.
      

  3.   

    使用AcceptEx()的一大好处是,
    你可以通过一次调用就完成接受客户端连接请求和接受数据(通过传送lpOutputBuffer参数)两件事情。
    也就是说,如果客户端在发出连接的同时传输数据,
    你的AcceptEx()调用在连接创建并接收了客户端数据后就可以立刻返回。
    这样可能是很有用的,但是也可能会引发问题,因为AcceptEx()必须等全部客户端数据都收到了才返回。
    具体来说,如果你在发出AcceptEx()调用的同时传递了 lpOutputBuffer参数,那么AcceptEx()不再是一项原子型的操作,
    而是分成了两步:接受客户连接,等待接收数据。当缺少一种机制来通知你的应用程序所发生的这种情况:“连接已经建立了,正在等待客户端数据”,这将意味着有可能出现客户端只发出连接请求,但是不发送数据。如果你的服务器收到太多这种类型的连接时,它将拒绝连接更多的合法客户端请求。这就是黑客进行“拒绝服务”攻击的常见手法。

    __in   PVOID lpOutputBuffer,
    也应该设置成NULL。
    调试的结果是ACCEPT同时SOCKET也关闭了。
      

  4.   

    1)什么信息都没有
    __in   PVOID lpOutputBuffer,         <---NULL
    __in   DWORD dwReceiveDataLength,    <---02)接收到一个shutdown的ACCEPT请求
    __in   DWORD dwReceiveDataLength,    <---0我使用127.0.0.1做的测试,
    不知道用另外一台机子connect是什么情况。
      

  5.   

    lpOutputBuffer是不可以为NULL的,至少需要接收两个地址。但是现在碰到的情况是立即返回模式下,无法取得地址。接收第一组数据的方式没有测试过。
      

  6.   


    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
      

  7.   

    换这个方式可以取到IP地址,但不是127.0.0.1
    ===============
    是否127.0.0.1,关键要看客户端连入时选择的是什么地址。就算是本机,如果连入时使用的不是127.0.0.1,那么得到的就不会是127.0.0.1,具体可以通过netstat看得到。如果取得的结果有异议,那么就有可能取错了。