在接受连接之前获取套接字的IP地址C++
我需要获取连接的IP地址,以查看它是否已经连接过(如果已经连接过,但没有连接,它会说离线)。 (使用非阻塞套接字)在接受连接之前获取套接字的IP地址C++
如何在没有首先接受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以及其在线/离线(已连接/未连接)。如果在我希望它在我接受新连接时显示Online时已连接,并使用上次使用的相同套接字号,而不是一起使用新套接字号。如果它没有,我希望它被添加到列表中。 (名单将有套接字号码)
如果这没有多大意义,我会尝试澄清更多。
如果插座数量你的意思是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()
调用后OS内核将接受所有到您设置的端口/本地IP的传入连接。这意味着远程主机的connect()
将成功返回,无论您是否拨打accept()
(如果您在侦听队列中有空间)。调用accept()
将只允许您与套接字进行交互。它不会改变远程主机看到的连接状态。
谢谢你们的帮助,好建议Pavel! – user1348950 2012-04-24 03:21:31
我不确定这是可能的,也不是一个有效的规范来实现你想要的。我要么:
接受任何连接,然后检查IP地址,断开其不在列表
(这可能是不适合你)连接配置上游的防火墙,这样的只允许IP地址通过。
很好的答案,谢谢。在某些情况下,同时进行#1和#2可能是有益的/必要的。例如,如果您需要向不同的客户端发送不同的数据。 – Zeek 2017-08-14 11:08:59
你所要求的不能用accept()
完成。直到它被接受并分配了新的SOCKET
句柄后,才能访问连接的信息。要获得连接信息预接受,您必须使用WSAAccept()
的回调功能。
无论哪种方式,都无法重新使用现有的SOCKET
句柄来建立新的连接。每个接受的连接必须具有自己的唯一SOCKET
句柄。不过,您可以将先前看到的IP中的新连接与ListView中的现有插槽关联起来。
如果绑定到通配符地址(INADDR_ANY
),则用于通信的IP地址在连接进入之前不会被确定(它将是数据包通过的接口中的一个)。相同的监听套接字可能导致多个IP地址上的接受连接。
如果你绑定到一个特定的地址,那么你已经知道你绑定的地址。
[拒绝来自主机的连接]可能的重复(http://*.com/questions/1116225/refusing-connection-from-a-host) – alexisdm 2012-04-22 01:23:54
当然,这会使用NAT来垃圾用户。 – 2012-04-22 05:59:49