在重叠IO操作中,使用WSARECV函数来接受客户端数据,问题是如何得到客户端IP地址?

解决方案 »

  1.   

    我给你写一小段代码,这是我服务器端,接收客户数据的工作线程,在Accept的时候就可以获取到客户的IP://工作线程
    DWORD WINAPI Proc_ServerWorkerThread(LPVOID lpParam)
    {
        CoInitialize(NULL); int nThreadNo = (int)lpParam; HANDLE hCompletionPort = g_ServerCtrl.m_hCompletionPort; DWORD ByteTransferred;
    LP_FI_SOCKET_DATA lpSocketData;
    LP_FI_IO_DATA lpIoData; 
    DWORD nQueryEvent; while (true)
    {
    nQueryEvent = WaitForSingleObject(g_hExitEvent, 0);
    switch (nQueryEvent)
    {
    case WAIT_FAILED:
    case WAIT_OBJECT_0:

    break;
    }
    } lpSocketData = NULL;
    lpIoData = NULL; BOOL bSuccess = GetQueuedCompletionStatus(hCompletionPort, &ByteTransferred, 
    (LPDWORD)&lpSocketData, (LPOVERLAPPED *)&lpIoData, INFINITE);

    if ((ByteTransferred == -1) && (lpIoData == NULL))
    { //退出信号到达,退出线程
    break;
    } if (!bSuccess)//在此套接字上有错误发生
    {
    DWORD dwIOError = GetLastError();
    if (dwIOError != WAIT_TIMEOUT)
    {
    if (lpSocketData != NULL)
    {
    g_ServerCtrl.DisConnectClient(lpSocketData, nThreadNo); 
    } continue;
    }
    } if (bSuccess && (lpSocketData != NULL) && (lpIoData != NULL))
    {
    if ((ByteTransferred == 0) && (lpIoData->OperType == PT_ACCEPT_POSTED))
    { //接受连接操作
    SOCKADDR_IN *LocalSockaddr = NULL;
    SOCKADDR_IN *RemoteSockaddr = NULL;
    int nLocalSockaddrLen = 0;
    int nRemoteSockaddrLen = 0; LP_FI_SOCKET_DATA lpClient = lpIoData->lpSocketData; lpClient->m_FI_Mutex.Lock();  GetAcceptExSockaddrs(lpIoData->DataBuf.buf, 0, sizeof(SOCKADDR_IN) + 16, sizeof(SOCKADDR_IN) + 16, 
    (SOCKADDR **)&LocalSockaddr, &nLocalSockaddrLen, (SOCKADDR **)&RemoteSockaddr, &nRemoteSockaddrLen); sprintf(lpClient->cLocalAddr, inet_ntoa(LocalSockaddr->sin_addr));
    sprintf(lpClient->cRemoteAddr, inet_ntoa(RemoteSockaddr->sin_addr));
    lpClient->nLocalPort = ntohs(LocalSockaddr->sin_port);
    lpClient->nRemotePort = ntohs(RemoteSockaddr->sin_port); if ((lpClient->nLocalPort == 0) && (lpClient->nRemotePort == 0))
    { //侦听端口被关闭
    lpClient->m_FI_Mutex.Unlock(); g_ServerCtrl.CloseSocket(lpClient->sClient, PT_PARENT_CLOSE); 
    }
    else
    {
    //printf("Socket : %d Accept\n", lpIoData->lpSocketData->sClient);
    //printf("LocalIP : %s\n", inet_ntoa(LocalSockaddr->sin_addr));
    //printf("LocalPort : %d\n", ntohs(LocalSockaddr->sin_port));
    //printf("RemoteIP : %s\n", inet_ntoa(RemoteSockaddr->sin_addr));
    //printf("RemotePort : %d\n", ntohs(RemoteSockaddr->sin_port)); CreateIoCompletionPort((HANDLE)lpClient->sClient, hCompletionPort, (DWORD)lpClient, 0); g_ServerCtrl.OnAccept(lpClient->sParent, lpClient->sClient, nThreadNo); //再投递一个Accept
    g_ServerCtrl.PostAccept(lpClient->sParent);  g_ServerCtrl.PostReceive(lpClient->sClient, lpClient->lpIoData); lpClient->m_FI_Mutex.Unlock();
    }
    continue;
    }

    if ((ByteTransferred == 0) && ((lpIoData->OperType == PT_RECV_POSTED) || (lpIoData->OperType == PT_SEND_POSTED)))
    { //客户机已经断开连接或者连接出现错误
    g_ServerCtrl.OnClose(lpSocketData->sParent, lpSocketData->sClient, nThreadNo);
    g_ServerCtrl.DisConnectClient(lpSocketData, nThreadNo);
    continue;
    } if ((ByteTransferred == 0) && (lpIoData->OperType == PT_PARENT_CLOSE))
    { //服务器关闭
    g_ServerCtrl.DisConnectClient(lpSocketData, nThreadNo);
    continue;
    }

    if (lpIoData->OperType == PT_RECV_POSTED)
    { //接收数据
    lpSocketData->m_FI_Mutex.Lock(); g_ServerCtrl.OnReceive(lpSocketData->sParent, lpSocketData->sClient, lpIoData->DataBuf.buf, ByteTransferred, nThreadNo);
    g_ServerCtrl.PostReceive(lpSocketData->sClient, lpIoData); lpSocketData->m_FI_Mutex.Unlock();
    continue;
    }

    if (lpIoData->OperType == PT_SEND_POSTED)
    { //发送完成
    g_ServerCtrl.m_ltIOList.RemoveAt(lpIoData);
    continue;
    }

    }  CoUninitialize(); return 1;
    }
      

  2.   

    SOCKET accept(
      SOCKET s,
      struct sockaddr FAR *addr,
      int FAR *addrlen
    );
    addr 
    [out] Optional pointer to a buffer that receives the address of the connecting entity, as known to the communications layer. The exact format of the addr parameter is determined by the address family that was established when the socket was created. addr的类型为out   相信楼主知道怎么获得了吧
      

  3.   

    我是用的是这个函数
    AcceptEx(listener,ov.s,&ov.buf[0],OV::initialReceiveSize,
    ov.addrlen,ov.addrlen,&ov.n,&ov);但是从中间得不到对方IP地址,郁闷之中
      

  4.   

    也就是从上面的ov.buf[0]这个缓存块中,如何取出地址信息?
      

  5.   

    http://topic.csdn.net/t/20040129/13/2685582.html