在接受连接 C++ 之前获取套接字的 IP 地址
Posted
技术标签:
【中文标题】在接受连接 C++ 之前获取套接字的 IP 地址【英文标题】:Get socket's IP address before accepting connection C++ 【发布时间】:2012-04-22 00:33:57 【问题描述】:我需要获取连接的 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 及其是否在线/离线(已连接/未连接)。如果它在我希望它在我接受新连接时显示在线之前已经连接,并使用它上次使用的相同套接字号,而不是一起使用一个新的。如果没有,我希望将其添加到列表中。 (列表将有套接字号)
如果这没有多大意义,我会尝试澄清更多。
【问题讨论】:
Refusing connection from a host 的可能重复项 当然,这会破坏带有 NAT 的用户。 【参考方案1】:accept()
无法满足您的要求。在连接被接受并分配新的SOCKET
句柄之前,您无法访问连接的信息。要获得连接信息预接受,您必须改用WSAAccept()
的回调功能。
无论哪种方式,都无法为新连接重用现有的SOCKET
句柄。每个接受的连接都必须有自己唯一的SOCKET
句柄。不过,您当然可以将来自先前看到的 IP 的新连接与 ListView 中的现有插槽相关联。
【讨论】:
【参考方案2】:如果 socket number 是指accept()
返回的数字,则根本不能依赖它的值。我的意思是,如果远程主机断开连接并再次连接,accept()
返回的值很可能会有所不同。依赖这个数字是没有意义的。
如果 socket number 是指数组中的位置,则可以将 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。这意味着无论您是否调用accept()
,远程主机的connect()
都会成功返回(前提是您在侦听队列中有空间)。调用accept()
将只允许您与套接字进行交互。它不会改变远程主机看到的连接状态。
【讨论】:
感谢大家的帮助,Pavel 的建议很好!【参考方案3】:我不确定实现您想要的是否可能也不是有效的规范。我会:
接受任何连接,然后检查 IP 地址,断开不在列表中的连接
(这可能不适合你)配置上游防火墙,只允许允许的 IP 地址通过。
【讨论】:
很好的答案,谢谢。在某些情况下,同时执行 #1 和 #2 可能是有益/必要的。例如,如果您需要向不同的客户端发送不同的数据。【参考方案4】:如果您绑定到通配符地址 (INADDR_ANY
),则在连接进入之前不会确定用于通信的 IP 地址(它将来自数据包通过的接口)。同一个侦听套接字可能会导致接受多个 IP 地址上的连接。
如果您绑定到特定地址,那么您已经知道您绑定到的地址。
【讨论】:
以上是关于在接受连接 C++ 之前获取套接字的 IP 地址的主要内容,如果未能解决你的问题,请参考以下文章
在Python中,当在localhost上接受TCP套接字连接时,无法获得正确的对等体IP地址。