Asci Zeichen per UDP senden



  • Na bis bind() dürfte doch alles klar sein? Danach schreibe ich die ganze Struktur nur noch mal neu, weil ich bind() ja die Adresse von addr mitgebe, die Funktion könnte theretisch ja sonst was da rein schreiben. Eigentlich hätte man nur die IP ändern müssen, aber da ich viel zu faul bin um nachzugucken was da jetzt wo garantiert wird, schreibe ich halt einfach alles neu. 🙂

    Du rufst bei bind mit sock auch einen Integer auf. Ich hab bislang immer nur gesehen, dass man die Variable als Typ SOCKET definiert und nicht als Int. Macht das einen Unterschied?

    Das ist nur ein hilfloser Versuch das Ganze irgendwie systemunabhängiger zu machen, nutze ruhig SOCKET, das ist besser.



  • Wozu ist das bind() denn jetzt gut, wenn du danach eh alles neu definierst und es für sendto() und recv() dann gar keine Rolle mehr spielt? Du hebst doch die vorher festgelegt "Bindung" mit der neuen Struktur direkt wieder auf, oder nicht? Bin grad nen bisschen verwirrt 😕 .



  • Ne. Wenn du etwas empfangen willst, egal ob mit recv() oder recvfrom() (die letzten Parameter sagen recvfrom() nicht von wo es empfangen soll, sondern recvfrom() speichert hier von wo empfangen wurde(!)) muss das Betriebssystem ja wissen, dass dein Socket an einem bestimmten Port auf etwas wartet. Und mit bind() machst du ihm das bekannt. Der Funktion bind() ist es auch egal, was du nachher mit der SOCKADDR_IN machst, die hat die Daten schon ans System weitergegeben.
    Siehe auch http://msdn.microsoft.com/en-us/library/ms737550(v=vs.85).aspx

    Edit:
    (connect() könnte hier eigentlich auch funktionieren, bzw. bei z.B. TCP-Sockets funktioniert das auf jeden Fall. Aber auch da kannst du immer erst nach bind() oder connect() etwas empfangen.

    Edit: Funktioniert genauso gut. 🙄

    #include <stdlib.h>
    #include <stdio.h>
    #include <WinSock2.h>
    
    #pragma comment (lib, "Ws2_32.lib")
    
    void errorexit(const char *msg, ...)
    {
      va_list argv;
      va_start(argv, msg);
      vprintf(msg, argv);
      va_end(argv);
      getchar(); //blah, Windows ;)
      exit(-1);
    }
    
    int main()
    {
      char buf[0x100] = "r";
      int sock, rval;
      struct sockaddr_in addr = {0};
      WSADATA wsa;
    
      if (WSAStartup(WINSOCK_VERSION, &wsa) != 0)
        errorexit("WSAStartup() failed with: %i.", 
          WSAStartup(WINSOCK_VERSION, &wsa));
    
      if (!(sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)))
        errorexit("socket() failed with: %i.", WSAGetLastError());
    
      addr.sin_addr.s_addr = inet_addr("192.168.0.127");
      addr.sin_family = AF_INET;
      addr.sin_port = htons(1911);
    
      if (connect(sock, (struct sockaddr*)&addr, sizeof(addr)) != 0)
        errorexit("connect() failed with: %i.", WSAGetLastError());
    
      if (send(sock, buf, strlen(buf), 0) < strlen(buf))
        errorexit("send() failed with: %i.", WSAGetLastError());
    
      while ((rval = recv(sock, buf, sizeof(buf) - 1, 0)) > 0)
      {
        buf[rval] = '\0';
        printf("%s", buf);
      }
    
      closesocket(sock);
      WSACleanup();
      return 0;
    }
    


  • mhh, also greift die recv() Funktion noch auf die Daten zu, die mit bind festgelegt wurde, obwohl vor dem eigentlichen recv() Aufruf diese Daten nochmals verändert wurden?
    Würde das Beispiel auch funktionieren, wenn ich bei der zweiten Strukturfestlegung alle Daten inkl. Port ändern würde?

    EDIT: Ich hab gelesen, dass recv() und recvfrom() einen bind implizieren. Ist das der Grund, warum es nun auch ohne bind() geht?

    Wenn ich allerdings auf unterschiedlichen Ports senden und empfangen möchte, brauche ich dann zwingend bind()?



  • Meiner schrieb:

    mhh, also greift die recv() Funktion noch auf die Daten zu, die mit bind festgelegt wurde, obwohl vor dem eigentlichen recv() Aufruf diese Daten nochmals verändert wurden?
    Würde das Beispiel auch funktionieren, wenn ich bei der zweiten Strukturfestlegung alle Daten inkl. Port ändern würde?

    Ja. Aber nutze einfach connect(), das sollte einfacher sein.



  • connect() legt im Falle von UDP ja den Standard Zielrechner fest.
    Wenn ich dann an einen Anderen etwas senden, oder von einem Anderen etwas empfangen möchste, muss ich die Struktur wieder entsprechend ändern und dann rec() oder sendto(), etc. aufrufen, richtig?
    Im Prinzip ist dann zwischen bind() und connect() (bei UDP) eigentlich kein Unterschied.

    Wenn das stimmt, dann versteh ich es langsam.



  • Um mal die Überschriftfrage zu beantworten (alles andere gehört nach WinAPI):

    Nein, du kannst keine ASCII Zeichen per UDP senden, du kannst Bytefolgen per UDP senden/empfangen, die du auf beiden Seiten u.a. als ASCII interpretieren kannst.



  • Dieser Thread wurde von Moderator/in rüdiger aus dem Forum C (C89 und C99) in das Forum WinAPI verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.



  • Also mit der Hilfe von cooky451, funktioniert die bind() Methode sehr gut. Allerdings benutze ich hier immer

    addr.sin_addr.s_addr    = INADDR_ANY;
    

    , wies ja auch von cooky451 benutzt wurde.

    Da ich aber nur von einer bestimmten IP Adresse empfangen möchte, habe ich mal die IP von meinem Umsetzter eingetragen. Dies hat aber den Effekt, dass das Programm wieder beim Empfangen hängen bleibt.

    Selbes Phänomen bei der connect() Methode. Der Code von cooky451 hierzu funktioniert ebenso wenig wie meine "Eigenkreationen".

    Anscheinend ist immer INADDR_ANY nötig, um etwas zu empfangen. Aber woran kann das liegen? Das Gerät sendet doch nicht plötzlich über eine andere IP 😕

    @rüdiger: Danke fürs Verschieben. Habe übersehen, dass mein Problem eher zu WinAPI gehört.

    @Wutz: Danke, aber das war mir eigentlich klar. Ich wollte ja mit meiner Frage auf etwas anderes hinaus. Die Überschrift ist wohl nen bisschen schlecht gewählt.


Anmelden zum Antworten