2012-04-22 76 views
2

我需要获取连接的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时已连接,并使用上次使用的相同套接字号,而不是一起使用新套接字号。如果它没有,我希望它被添加到列表中。 (名单将有套接字号码)

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

+0

[拒绝来自主机的连接]可能的重复(http://stackoverflow.com/questions/1116225/refusing-connection-from-a-host) – alexisdm 2012-04-22 01:23:54

+0

当然,这会使用NAT来垃圾用户。 – 2012-04-22 05:59:49

回答

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()调用后OS内核将接受所有到您设置的端口/本地IP的传入连接。这意味着远程主机的connect()将成功返回,无论您是否拨打accept()(如果您在侦听队列中有空间)。调用accept()将只允许您与套接字进行交互。它不会改变远程主机看到的连接状态。

+0

谢谢你们的帮助,好建议Pavel! – user1348950 2012-04-24 03:21:31

1

我不确定这是可能的,也不是一个有效的规范来实现你想要的。我要么:

  1. 接受任何连接,然后检查IP地址,断开其不在列表

  2. (这可能是不适合你)连接配置上游的防火墙,这样的只允许IP地址通过。

+0

很好的答案,谢谢。在某些情况下,同时进行#1和#2可能是有益的/必要的。例如,如果您需要向不同的客户端发送不同的数据。 – Zeek 2017-08-14 11:08:59

2

你所要求的不能用accept()完成。直到它被接受并分配了新的SOCKET句柄后,才能访问连接的信息。要获得连接信息预接受,您必须使用WSAAccept()的回调功能。

无论哪种方式,都无法重新使用现有的SOCKET句柄来建立新的连接。每个接受的连接必须具有自己的唯一SOCKET句柄。不过,您可以将先前看到的IP中的新连接与ListView中的现有插槽关联起来。

0

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

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