簡體   English   中英

POSIX UDP套接字未綁定到正確的IP

[英]POSIX UDP socket not binding to correct IP

我正在編寫一個大學項目,涉及使用POSIX套接字和C ++編寫聊天客戶端和服務器。

客戶端應該使用P2P相互交談,例如每個客戶端都有自己的開放UDP套接字,通過該套接字,他可以從其他客戶端發送消息或從其他客戶端接收消息。

我的問題是2倍:

  1. 我的UDPSocket類構造函數似乎完全忽略了端口號,無論該參數如何,都綁定到端口65535。
  2. 該端口綁定到IP 255.255.255.255,而不是我自己的IP(10.0.0.3),或者至少是我調用getpeername時得到的。

據我所知,傳遞INADDR_ANY應該綁定到我的本地地址,傳遞端口號0應該使操作系統選擇一個空閑端口,我在做什么錯?

這是我的UDPSocket類的構造函數:

UDPSocket::UDPSocket(int port){
socket_fd = socket (AF_INET, SOCK_DGRAM, 0);

// clear the s_in struct
bzero((char *) &in, sizeof(in));  /* They say you must do this    */

//sets the sin address
in.sin_family = (short)AF_INET;
in.sin_addr.s_addr = htonl(INADDR_ANY);    /* WILDCARD */
in.sin_port = htons((u_short)port);

fsize = sizeof(from);

//bind the socket on the specified address
if(bind(socket_fd, (struct sockaddr *)&in, sizeof(in))<0){
    perror ("Error naming channel");
}
}

這是初始化:

m_Socket = new UDPSocket(0);

這是我用來檢索綁定地址的方法:(UDPSocket繼承Socket)

std::string Socket::GetSocketAddress()
{
    struct sockaddr_in  addr;
    int len = sizeof(addr);
    getpeername(socket_fd, (struct sockaddr*)&addr, (socklen_t*)&len);

    char ipAddressBuffer[50];
    memset(ipAddressBuffer, 0, sizeof(ipAddressBuffer));
    sprintf(ipAddressBuffer, "%s:%d", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));

    return ipAddressBuffer;
}

任何幫助,我們將不勝感激,Avi。

您正在使用getpeername ,它為您提供了已連接套接字的遠程地址。 如果檢查getpeername()的返回值,則應指示失敗。

  • 您需要使用getsockname ()而不是getpeername()來獲取本地套接字的地址
  • 您需要檢查getsockname()是否成功。

請注意,您的套接字已綁定到特殊的0.0.0.0地址,這意味着“所有本地接口”,因此getsockname()也將返回該地址。

回答更普遍的問題“如何使用UDP建立對等通信”:

使用UDP套接字,雖然可以使用connect ,但是通常不希望這樣做,因為這connect您限制為每個套接字只能有一個對等端。 相反,您希望在每個對等sendto使用單個未連接的UDP套接字,同時使用sendtorecvfrom系統調用來發送和接收每個數據包具有不同地址的數據包。

sendto函數接收一個數據包和一個對等地址以將其發送到,而recvfrom函數返回一個數據包及其從其對等地址。 只需一個套接字,就無需與selectpoll進行多路復用-您只需調用recvfrom即可從任何來源獲取下一個數據包。 當您收到數據包時,您還將獲得對等地址以將數據包發送回。

在啟動時,您的對等方將創建一個套接字,並將其綁定到INADDR_ANY (允許它在計算機上的任何接口或廣播地址上接收數據包),並為程序分配特定端口或端口0(從而使OS能夠選擇任何端口)。未使用的端口)。 在后一種情況下,您需要使用getsockname來獲取端口並將其報告給用戶。 一旦插座設置,對等程序可以sendto任何對它所知道的,或者recvfrom所有任意端點(包括那些它還不知道)。

因此,唯一棘手的部分是引導程序-使第一個數據包流動,以便對等方可以接收它們並找出要與之通信的對等地址。 一種方法是在啟動每個對等方時在命令行上指定對等方地址。 您將開始沒有參數的第一個(因為它還沒有同級)。 它只會從socket設置后恢復(revvfrom)以獲取來自同級的數據包。 從第二個開始,以第一個的地址作為參數。 它向第一個對等方發送一個(或幾個)數據包,然后第一個對等方將在收到第一個數據包后立即知道新對等方。 現在,在命令行上使用前兩個的地址啟動第三個客戶端...

暫無
暫無

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

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