2016-08-19 3 views
2

Ich versuche Socket-Programmierung mit C/C++ zu lernen. Ich habe zwei kleine UDP-Sender geschrieben. Einer ist mit bind() ing, ein anderer ist ohne bind() ing. Ich habe beide Programme auf einer Remote IP erstellt. Zur gleichen Zeit baute ich einen kleinen UDP-Empfänger auf meinem lokalen System. Ich habe versucht, eine UDP-Nachricht von beiden Senderprogrammen an meinen lokalen Empfänger zu senden. Der Empfänger kann jedoch nur eine Nachricht vom Sender mit bind() empfangen. Und es muss an dieselbe Portnummer mit dem Ziel gebunden sein. Ansonsten funktioniert es auch mit bind() nicht. Aber als ich das Senderprogramm ohne bind() in mein lokales System verschoben und die Nachricht an "127.0.0.1" gesendet habe, funktionierte es.müssen UDP-Quellport und Zielport übereinstimmen?

Also für mich, es scheint wie Udp-Paket lokal senden der src-Port und Ziel-Port kann verschiedene Zahlen sein. Wenn jedoch das Udp-Paket von einer anderen IP-Adresse gesendet wird, muss der sendende und der empfangende Port eine übereinstimmende Portnummer haben. Ist das richtig?

Hier ist mein udp Senderprogramm:

#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

Nein, ich denke, Sie sind verwirrt über ein paar wichtige Punkte. Hier ist ein gutes Tutorial, das helfen könnte: [Programmierung mit UDP-Sockets] (https://www.cs.rutgers.edu/~pxk/417/notes/sockets/udp.html). Dieser Link diskutiert weiter die Rolle von [bind] (http://linux.die.net/man/2/bind): http://stackoverflow.com/questions/3057029/do-i-have-to-bind- a-udp-socket-in-mein-client-programm-zu-empfange-daten-i-always-g – paulsm4

+2

Jeder UDP (und TCP) Endpunkt wird durch ein (Adresse, Port) * Paar * gekennzeichnet. Das entspricht ziemlich gut (Maschine, Programm). Ein Port ist eine Eigenschaft nur eines Endpunkts, nicht des gesamten Kommunikationskanals. Daher ist es nicht erforderlich, dass derselbe Port an beiden Enden verwendet wird. Normalerweise ist es nicht. –

Antwort

4

mir Also, es scheint, wie lokal die src-Port UDP-Paket sendet und dest Port können verschiedene Zahlen.

Korrekt.

Wenn Sie jedoch ein UDP-Paket von einer anderen IP-Adresse senden, müssen der sendende und der empfangende Port eine übereinstimmende Portnummer haben. Ist das richtig?

Nein. Es tut es nicht. Bei der Antwort müssen Sie sicherstellen, dass der Quellport des empfangenen Datagramms, das über recvfrom() zurückgegeben wird, als Zielport des Antwortdatagramms in sendto() verwendet wird.

Verwandte Themen