在接受连接C ++之前获取套接字的IP地址

时间:2012-04-22 00:33:58

标签: c++ c sockets winsock2

我需要获取连接的IP地址以查看它是否先前已连接(检查ips列表,如果它先前已连接但已不再连接,则会说离线)。 (使用非阻塞套接字)

如果没有先接受IP,我怎样才能获得IP。

///

    case FD_ACCEPT:
        int W;
        for(W = 0;W <= ListView_GetItemCount(GetDlgItem(HwND,IDC_IPLIST));W++){

那么我就要在列表视图中检查IP以查看它之前是否已连接。如果有,我想使用上次使用的套接字号。

这就是我现在接受连接的方式

        case FD_ACCEPT: 
        while(Client[F] != NULL)
        {
        F++;
        }
        Client[F]=accept(wParam,(LPSOCKADDR)&ServAdr,&AdrLen);
        break;

所以要把它分解......

我想根据先前连接的IP列表检查传入连接。此列表将具有IP以及其在线/离线(已连接/未连接)。如果它在我希望它接受新连接之前显示在线之前已连接,并使用它上次使用的相同套接字号而不是一起使用新的套接字号。如果它还没有我希望它被添加到列表中。 (列表将有套接字号)

如果这没有多大意义,我会尝试澄清一点。

4 个答案:

答案 0 :(得分:2)

accept()无法满足您的要求。在接受连接并分配新的SOCKET句柄之前,您无权访问连接的信息。要获得预先接受的连接信息,您必须使用WSAAccept()的回调功能。

无论哪种方式,都无法为新连接重用现有的SOCKET句柄。每个接受的连接都必须有自己唯一的SOCKET句柄。您当然可以将先前看到的IP中的新连接与ListView中的现有插槽相关联。

答案 1 :(得分:1)

我不确定是否有可能也无法达到您想要的效率规范。我要么:

  1. 接受任何连接,然后检查IP地址,断开列表中没有的连接

  2. (这可能不适合您)配置上游防火墙,以便只允许通过允许的IP地址。

答案 2 :(得分:1)

如果套接字编号表示accept()返回的数字,则根本不能依赖它的值。我的意思是,如果远程主机断开并再次连接,accept()返回的值很可能会有所不同。依靠这个数字是没有意义的。

如果套接字编号表示数组中的位置,则可以将accept()返回的值分配给临时变量:

SOCKET tmpSock;
sockaddr_in tmpAddr;
int namelen;
typedef struct { /*...*/ } TClient;
TClient Client[MAX_CLIENTS];
/*...*/
tmpSock = accept(/*...*/);
namelen = sizeof(tmpAddr);
getpeername(tmpSock, (sockaddr*)&tmpAddr,&namelen);
/*...*/
//looking for tmpAddr.sin_addr in your list and calculating
//the list position - F
/*...*/
Client[F].Socket = tmpSock;
Client[F].IsConnected = true;
Client[F].Address = tmpAddr.sin_addr;

请记住,在listen()调用之后,操作系统内核将接受您设置的端口/本地IP的所有传入连接。这意味着无论您是否呼叫connect(),远程主机的accept()都将成功返回(前提是您在侦听队列中有空间)。调用accept()只允许您与套接字进行交互。它不会更改远程主机看到的连接状态。

答案 3 :(得分:0)

如果绑定到通配符地址(INADDR_ANY),则在连接进入之前不会确定用于通信的IP地址(它将来自数据包通过的接口)。相同的侦听套接字可以导致多个IP地址上的已接受连接。

如果绑定到特定地址,那么您已经知道绑定的地址。