Socketprogrammierung- Programm stop bei recvfrom



  • Hallo,

    ich möchte gerne eine Kommunikation zwischen zwei Rechner (auf einem Ubuntu( Eclipse C++), auf dem anderen Windows 10(Matlab 2016b)) aufbauen. Der C++-Rechner soll als Server arbeiten und der Matlabrechner als Client. Das senden per UDP nach Matlab klappt dabei wunderbar, allerdings habe ich Probleme damit Daten von Matlab zu C++ zu schicken. Hierbei sei gesagt, dass auf Ubuntuseite mit netcat -l -u port und anschließenden Senden der Daten aus Matlab mit fwrite() die Daten ankommen, es also nicht an der Verbindung zwischen den Rechnern liegen sollte. Wenn mein Programm bei recvfrom() ankommt das Programm nicht mehr weiter, obwohl ich die Daten aus Matlab sende. Select() liefert mir auch nur 0 als return value, was eigentlich bedeutet, dass der Socket nicht verfügbar ist? Wenn das so ist verstehe ich nicht wieso er es nicht ist. Ich wäre sehr dankbar, wenn mir dabei jemand helfen kann und mir dabei hilft zu sagen wo der Fehler liegt.

    int Socket=socket(AF_INET, SOCK_DGRAM,0);
    /*FD_ZERO(&SockSet);
    FD_SET(Socket,&SockSet);
    sTimeval.tv_sec=0.1;
    sTimeval.tv_usec=0;
    int status=select(Socket+1,&SockSet,(fd_set*)NULL,(fd_set *)NULL,&sTimeval);
    cout<<status<<endl;*/
    
    if(Socket!=-1)
    cout<<"Socket created"<<endl;
    else
    cout<<"Socket not created"<<endl;
    
    unsigned short port=4012;
    
    struct in_addr serverIP;
    
    (void)inet_pton(AF_INET,"192.168.56.101", &serverIP);
    
    struct sockaddr_in server;
    memset(&server,0, sizeof(server));
    server.sin_family=AF_INET;
    server.sin_addr=serverIP;
    server.sin_port=htons(port);
    
    if(bind(Socket,(struct sockaddr*)&server, sizeof(&server))!=1)
    cout<<"Binding successful"<<endl;
    else
    cout<<"Binding failed";
    
    struct sockaddr client;
    memset(&client, 0, sizeof(client));
    socklen_t clientlen=0;
    struct sockaddr_in* client_in;
    memset(&client_in,0,sizeof(client_in));
    
    cout<<"warten vor recv"<<endl;
    ssize_t bytesread=recvfrom(Socket, &msg, sizeof(msg), 0, &client,&clientlen);
    cout<<(int)bytesread<<endl;
    cout<<msg<<endl;
    
    client_in=(struct sockaddr_in*)&client;
    char* client_adr=inet_ntoa(client_in->sin_addr);
    printf("%s Port%d\n", client_adr, ntohs(client_in->sin_port));
    
    if (bytesread == -1) {
    cerr << "Fehler beim empfangen" << endl;
    int status = close(Socket);
    if (status == 0)
    cout << "Socket closed" << endl;
    else if (status == -1)
    cout << "Socket not closed" << endl;
    return (1);
    
    }
    
    //Wenn Infos ueber Client nicht schon vorher aus recvfrom()
    /*struct in_addr clientIP;
    (void)inet_pton(AF_INET,"192.168.2.102", &clientIP);
    struct sockaddr_in client;
    memset(&client,0, sizeof(client));
    client.sin_family=AF_INET;
    client.sin_addr=clientIP;
    client.sin_port=htons(5532);*/
    
    char msg2[]="12345";
    ssize_t bytessent=sendto(Socket,msg2,strlen(msg2),0,(struct sockaddr*)&client,sizeof(client));
    cout<<(int)bytessent<< " bytes were sent"<<endl;
    
    int status=close(Socket);
    if(status==0)
    cout<<"Socket closed"<<endl;
    else if(status==-1)
    cout<<"Socket not closed"<<endl;
    
    return 0;
    }
    

    Hierzu ist noch zu sagen, dass auch beim verwenden von fd_set nicht mehr passiert. Hier wartet er dann wohl die angegebene Zeit ob der Socket ready ist un springt, wenn das nicht der Fall ist, nach 10s weiter und dann bleibt das Programm bei recvfrom() wieder stehen.

    Viele Grüße,
    Erano1



  • Erano1 schrieb:

    [...] UDP [...]

    Gibts einen speziellen Grund UDP (statt TCP) zu verwenden?



  • Ja, in der Anwendung ist die Geschwindigkeit sehr wichtig.



  • klappt denn alles in der einfachen TCP implementierung? wieviel zulangsam ist es? und was ist das problem, latenz oder bandbreite?



  • Das habe ich ehrlich gesagt selber nicht getestet, sondern von Vorgängern so übernommen. Aber abgesehen davon, kannst du bzw. keiner sagen oder vermuten, wo der Fehler sein könnte? Wenn ich wie gesagt mit Matlab oder auch über einen anderen Rechner mit C++ Pakete mit sendto() an den Port schicke kommen die Pakete auf jeden Fall an. Ich verstehe nur dann nicht, wieso ich diese nicht mit recvfrom() empfangen kann und er bei recvfrom() im Programm nicht mehr weiter kommt.



  • klingt das nicht als ob das sendende program einen fehler hat?



  • Auch, wenn die Daten bei netcat empfangen werden? Habe als erstes vermutet, dass Matlab vielleicht die Daten in irgendeiner Form sendet die dem C++ Programm nicht passt. Wie die Daten von Matlab aussehen habe ich mir noch nicht angesehen, allerdings funktioniert es auch nicht von C++ zu C++, obwohl auch hier die Daten beim senden mit C++ und sendto() über netcat -l -u 4012 korrekt empfangen werden. Daher würde ich vermuten, dass auf der Serverseite irgendetwas mit dem recvfrom nicht stimmt, wobei ich mir da nicht erklären kann was. Da hast du oder irgendjemand keine Idee?



  • Lustigerweise wird das Programm jetzt auch über recvfrom hinaus ausgeführt, nachdem ich es einmal im debug mode gestartet habe. Allerdings werden keine Daten emfpangen, obwohl sie gesendet werden. Auch wenn ich vorher listen() und accept() benutzte (ich weiß, dass das für gewöhnlich bei einer UDP-Verbindung nicht notwending ist) funktioniert es nicht. Beide Funktionen geben -1 zurück, was beudetet, dass ja irgendwas mit dem Socket nicht funktioniert, oder? Wenn ja, kann jemand erkennen was da falsch läuft?



  • Klar, errno kann das.



  • Mittlerweile habe ich den Fehler endteckt. Beim binden habe ich sizeof(&server) übergeben, anstatt sizeof(server). Gleichzeitig habe ich dummerweise if bind...=!1 anstatt -1 abgefragt. Das heißt es lag daran, dass er nicht erfolgreich binden konnte.


Anmelden zum Antworten