2016-08-19 676 views
2

我想學習用c/C++編寫socket編程。我寫了兩個小的udp發送者。一個是綁定(),另一個沒有綁定()。我在遠程IP上構建了兩個程序。同時,我在本地系統上構建了一個小型udp接收器。我試圖從兩個發件人程序發送udp消息到我的本地接收器。但是接收者只能通過bind()方法接收發件人的消息。它必須綁定在與目的地相同的端口號上。否則,即使使用bind(),它仍然不起作用。 但是,當我移動發件人程序沒有綁定()到我的本地系統,併發送消息到「127.0.0.1」它的工作。做udp源端口和目標端口必須匹配嗎?

所以對我來說,好像在本地發送udp數據包的src端口和dest端口可以是不同的數字。但是,當從不同的IP地址發送udp數據包時,發送和接收端口必須具有匹配的端口號。是對的嗎?

這裏是我的UDP發送程序:

#include <iostream> 
#include <cstring> 
#include <cerrno> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 

using namespace std; 

int main(int argc, char *argv[]){ 
    if(argc!=2){ 
     cout<<"need arg"<<endl; 
     return 1; 
    } 
    int sfd = socket(AF_INET, SOCK_DGRAM, 0); 
    struct sockaddr_in des; 
    des.sin_family = AF_INET; 
    des.sin_port = 9999; 
    des.sin_addr.s_addr = inet_addr("my ip address"); //I used "127.0.0.1" when I tried it locally. 

    /* this is all the difference between the sender with and without bind() 
    struct sockaddr_in sai; 
    sai.sin_family = AF_INET; 
    sai.sin_port = 5001; 
    sai.sin_addr.s_addr = INADDR_ANY; 
    if(bind(sfd, (struct sockaddr *)&sai, sizeof sai)==-1){ 
     cout<<"bind:"<<strerror(errno)<<endl; 
     _exit(1); 
    } 
    cout<<"binded successfully"<<endl; 
    */ 

    int byt = sendto(sfd, argv[1], strlen(argv[1])+1, 0, (struct sockaddr *)&des, sizeof des); 
    cout<<byt<<endl; 
    if(byt<0){ 
     cout<<"sendto"<<strerror(errno)<<endl; 
    } 

    return 0; 
} 
+4

不,我認爲你對幾個關鍵點感到困惑。這是一個很好的教程,可能會有所幫助:[用UDP套接字編程](https://www.cs.rutgers.edu/~pxk/417/notes/sockets/udp.html)。此鏈接進一步討論[bind](http://linux.die.net/man/2/bind)的作用:http://stackoverflow.com/questions/3057029/do-i-have-to-bind- a-udp-socket-in-my-client-program-to-receive-data-i-always -g – paulsm4

+2

每個UDP(和TCP)端點都由一個(地址,端口)*對*表徵。這非常適合(機器,程序)。端口是單獨一個端點的特性,而不是整個通信信道的特性,所以不需要在兩端使用相同的端口。通常情況下,它不是。 –

回答

4

所以對我來說,這似乎是發送UDP數據包的本地源端口和目的端口可以是不同的數字。

正確。

但是,當從不同的IP地址發送udp數據包時,發送和接收端口必須具有匹配的端口號。是對的嗎?

不,它不。答覆時要做的是確保使用接收到的數據報的源端口(通過recvfrom()返回)作爲回覆數據報的目標端口sendto()