我需要获取连接的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以及其在线/离线(已连接/未连接)。如果它在我希望它接受新连接之前显示在线之前已连接,并使用它上次使用的相同套接字号而不是一起使用新的套接字号。如果它还没有我希望它被添加到列表中。 (列表将有套接字号)
如果这没有多大意义,我会尝试澄清一点。
答案 0 :(得分:2)
accept()
无法满足您的要求。在接受连接并分配新的SOCKET
句柄之前,您无权访问连接的信息。要获得预先接受的连接信息,您必须使用WSAAccept()
的回调功能。
无论哪种方式,都无法为新连接重用现有的SOCKET
句柄。每个接受的连接都必须有自己唯一的SOCKET
句柄。您当然可以将先前看到的IP中的新连接与ListView中的现有插槽相关联。
答案 1 :(得分:1)
我不确定是否有可能也无法达到您想要的效率规范。我要么:
接受任何连接,然后检查IP地址,断开列表中没有的连接
(这可能不适合您)配置上游防火墙,以便只允许通过允许的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地址上的已接受连接。
如果绑定到特定地址,那么您已经知道绑定的地址。