解决方案 »

  1.   

    10057: A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied. 你的SOCKET有效?是accept返回的有效的SOCKET句柄吗?
      

  2.   

    应该是吧,客户端的验证信息都已经发过来了,而且已经验证成功了...
    代码如下:bool CSocketServer::DoAccept(lpREQUEST_CONTEXT lpAcceptContext)
    {
    SOCKADDR_IN * pClientAddr = NULL;
    SOCKADDR_IN * pLocalAddr  = NULL; int nSockAddrLen = sizeof(SOCKADDR_IN);
    m_lpfnGetAcceptExSockAddrs //acceptex 之友 用来获取 客户端发送回来的第一组数据、本地地址信息,客户端地址信息
    (
    lpAcceptContext->wsaBuffer.buf,
    lpAcceptContext->wsaBuffer.len -( (nSockAddrLen + 16) * 2) ,
    nSockAddrLen  + 16 , 
    nSockAddrLen  + 16 , 
    (LPSOCKADDR*)&pLocalAddr  ,
    &nSockAddrLen , 
    (LPSOCKADDR*)&pClientAddr , 
    &nSockAddrLen
    );

    string   ip     = inet_ntoa(pClientAddr->sin_addr);
    int      port   = ntohs(pClientAddr->sin_port);
    SOCKET   sock   = GetAcceptContextSocket(lpAcceptContext);   //获取之前投递Accept请求时插入的socket
    APP_TYPE type = GetClientType(lpAcceptContext->wsaBuffer.buf); if(  APP_NULL == type
    || !IsLoginCmd(lpAcceptContext->wsaBuffer.buf))  //如果验证失败
    { m_ploger->formatMsg("验证失败,断开连接:%s:%d.",ip.c_str(),port); RELEASE_SOCKET(sock);
    }
    else
    {
    lpSOCKET_CONTEXT pSocketContext = GetClientSockContext(type , ip.c_str()); if(!pSocketContext)
    {
        m_ploger->formatMsg("不存在该客户端,端类型:%s 地址:%s.",GetAppTypeName(type).c_str(),ip.c_str());
    RELEASE_SOCKET(sock); }
    else
    {
    pSocketContext->sock = sock;
    pSocketContext->ip   = ip;
    pSocketContext->port = port;
    pSocketContext->type = type; setsockopt(sock,
    SOL_SOCKET,
    SO_UPDATE_ACCEPT_CONTEXT,
    (char*)&m_plisenContext->sock,
    sizeof(m_plisenContext->sock)
    ); CreateIoCompletionPort((HANDLE)sock,m_hIOCompletionPort,(DWORD)pSocketContext,0); SetClientOnline(pSocketContext);
     
    m_ploger->formatMsg("客户端 类型:%s 地址:%s:%d 登陆成功.",GetAppTypeName(type).c_str(),
    ip.c_str(),port);  
    lpREQUEST_CONTEXT pRecvContext = pSocketContext->GetNewContext(REQUEST_RECV); if(!PostRecv(pSocketContext,pRecvContext))   //如果客户端投递recv请求失败,断开连接,并设置客户端离线
    SetClientUnline(pSocketContext);
     
    }

    }
    return PostAccept(lpAcceptContext);
    }bool CSocketServer::PostRecv(lpSOCKET_CONTEXT pSockContext,lpREQUEST_CONTEXT lpRecvContext)
    {
    lpRecvContext->ZeroBuffer();
    OVERLAPPED * pOverlapped = &lpRecvContext->overlapped;
    WSABUF     * pWsaBuffer  = &lpRecvContext->wsaBuffer; DWORD dwFlags = 0;
    DWORD dwBytes = 0; int nBytesRecv = WSARecv( 
    pSockContext->sock,
    pWsaBuffer,
    1,
    &dwBytes,
    &dwFlags,
    pOverlapped,
    NULL
    ); // 如果返回值错误,并且错误的代码并非是Pending的话,那就说明这个重叠请求失败了
    if ((SOCKET_ERROR == nBytesRecv) && (WSA_IO_PENDING != WSAGetLastError()))
    {
    m_ploger->formatMsg("客户端投递Recv请求失败 类型:%s 地址:%s,Socket错误代码:%d",
    GetAppTypeName(pSockContext->type).c_str(),pSockContext->ip.c_str(),WSAGetLastError()); SetClientUnline(pSockContext);
    return false;
    } return true;
    }