簡體   English   中英

接受連接C ++之前獲取套接字的IP地址

[英]Get socket's IP address before accepting connection C++

我需要獲取連接的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以及其在線/離線(已連接/未連接)。 如果它在我接受新連接時顯示為“聯機”之前已連接,並使用與上次使用的套接字號相同,而不是一起使用新的套接字號。 如果還沒有,我希望將其添加到列表中。 (列表中將帶有套接字號)

如果這沒有多大意義,我將嘗試進一步澄清。

您要求的內容無法通過accept() 您必須先接受連接信息並分配新的SOCKET句柄,才能訪問該連接的信息。 要獲得連接信息的預先接受,必須使用WSAAccept()的回調功能。

無論哪種方式,都無法將現有的SOCKET句柄重用於新連接。 每個接受的連接必須具有自己唯一的SOCKET句柄。 當然,您當然可以將以前看到的IP的新連接與ListView中的現有插槽關聯。

我不確定實現您想要的內容的可能或有效的規范。 我會:

  1. 接受任何連接,然后檢查IP地址,斷開不在列表中的連接

  2. (這可能不適合您)配置上游防火牆,以便僅允許通過允許的IP地址。

如果用套接字號表示由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的所有傳入連接。 這意味着無論您是否調用accept() connect() ,遠程主機的connect()都會成功返回(假設偵聽隊列中有空間)。 調用accept()將只允許您與套接字進行交互。 它不會更改遠程主機看到的連接狀態。

如果您綁定到通配符地址( INADDR_ANY ),則直到連接建立時才確定用於通信的IP地址(它將是數據包通過的接口中的一個)。 同一偵聽套接字可以導致在多個IP地址上接受連接。

如果綁定到特定地址,則您已經知道綁定到的地址。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM