UDP in C++



  • Danke für die schnelle Antwort 🙂
    aber könntest du das vielleicht noch ein bisschen genauer beschreiben?

    ich kann zwar einigermaßen c++ programmieren, aber mit sockets kenne ich mich nicht so gut aus 🙄

    danke 🙂

    Viele Grüße,
    Freddy





  • Hallo

    Da du offenbar den Builder benutzt solltest du besser die entsprechende UDP-Clientkomponente aus dem Indy-Packet benutzen.

    bis bald
    akari



  • Hallo,

    wenn ich versuche das Programm zu compilieren:

    /*
    ** listener.c -- a datagram sockets "server" demo
    */
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <errno.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    
    #define MYPORT 5999	// the port users will be connecting to
    
    #define MAXBUFLEN 100
    
    int main(void)
    {
    	int sockfd;
    	struct sockaddr_in my_addr;	// my address information
    	struct sockaddr_in their_addr; // connector's address information
    	socklen_t addr_len;
    	int numbytes;
    	char buf[MAXBUFLEN];
    
    	if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
    		perror("socket");
    		exit(1);
    	}
    
    	my_addr.sin_family = AF_INET;		 // host byte order
    	my_addr.sin_port = htons(MYPORT);	 // short, network byte order
    	my_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP
    	memset(&(my_addr.sin_zero), '\0', 8); // zero the rest of the struct
    
    	if (bind(sockfd, (struct sockaddr *)&my_addr,
    		sizeof(struct sockaddr)) == -1) {
    		perror("bind");
    		exit(1);
    	}
    
    	addr_len = sizeof(struct sockaddr);
    	if ((numbytes = recvfrom(sockfd, buf, MAXBUFLEN-1 , 0,
    		(struct sockaddr *)&their_addr, &addr_len)) == -1) {
    		perror("recvfrom");
    		exit(1);
    	}
    
    	printf("got packet from %s\n",inet_ntoa(their_addr.sin_addr));
    	printf("packet is %d bytes long\n",numbytes);
    	buf[numbytes] = '\0';
    	printf("packet contains \"%s\"\n",buf);
    
    	close(sockfd);
    
    	return 0;
    }
    

    bekomme ich folgende Fehlermeldungen:

    [C++ Fehler] Unit1.c(7): E2209 include-Datei 'UNISTD.H' kann nicht geöffnet werden.
    [C++ Fehler] Unit1.c(11): E2209 include-Datei 'SYS\SOCKET.H' kann nicht geöffnet werden.
    [C++ Fehler] Unit1.c(12): E2209 include-Datei 'NETINET\IN.H' kann nicht geöffnet werden.
    [C++ Fehler] Unit1.c(13): E2209 include-Datei 'ARPA\INET.H' kann nicht geöffnet werden.
    [C++ Fehler] Unit1.c(22): E2450 Undefinierte Struktur 'sockaddr_in'
    [C++ Fehler] Unit1.c(22): E2449 Größe von 'my_addr' unbekannt oder Null
    [C++ Fehler] Unit1.c(22): E2450 Undefinierte Struktur 'sockaddr_in'
    [C++ Fehler] Unit1.c(22): E2450 Undefinierte Struktur 'sockaddr_in'
    [C++ Fehler] Unit1.c(22): E2449 Größe von 'my_addr' unbekannt oder Null
    [C++ Fehler] Unit1.c(23): E2450 Undefinierte Struktur 'sockaddr_in'
    [C++ Fehler] Unit1.c(23): E2449 Größe von 'their_addr' unbekannt oder Null
    [C++ Fehler] Unit1.c(23): E2450 Undefinierte Struktur 'sockaddr_in'
    [C++ Fehler] Unit1.c(23): E2450 Undefinierte Struktur 'sockaddr_in'
    [C++ Fehler] Unit1.c(23): E2449 Größe von 'their_addr' unbekannt oder Null
    [C++ Fehler] Unit1.c(24): E2451 Undefiniertes Symbol 'socklen_t'
    [C++ Fehler] Unit1.c(24): E2379 In Anweisung fehlt ;
    [C++ Fehler] Unit1.c(25): E2140 Deklaration hier nicht zulässig
    [C++ Fehler] Unit1.c(26): E2140 Deklaration hier nicht zulässig
    [C++ Fehler] Unit1.c(28): E2451 Undefiniertes Symbol 'AF_INET'
    [C++ Fehler] Unit1.c(28): E2451 Undefiniertes Symbol 'SOCK_DGRAM'
    [C++ Warnung] Unit1.c(28): W8065 Aufruf der Funktion 'socket' ohne Prototyp
    [C++ Fehler] Unit1.c(33): E2451 Undefiniertes Symbol 'sin_family'
    [C++ Fehler] Unit1.c(34): E2451 Undefiniertes Symbol 'sin_port'
    [C++ Warnung] Unit1.c(34): W8065 Aufruf der Funktion 'htons' ohne Prototyp
    [C++ Fehler] Unit1.c(35): E2451 Undefiniertes Symbol 'sin_addr'
    [C++ Fehler] Unit1.c(35): E2451 Undefiniertes Symbol 'INADDR_ANY'
    [C++ Fehler] Unit1.c(36): E2451 Undefiniertes Symbol 'sin_zero'
    [C++ Fehler] Unit1.c(36): E2228 Zu viele Fehlermeldungen oder Warnungen
    

    Woher bekomme ich die fehlenden Header Dateien?

    akari schrieb:

    Hallo

    Da du offenbar den Builder benutzt solltest du besser die entsprechende UDP-Clientkomponente aus dem Indy-Packet benutzen.

    bis bald
    akari

    Wie benutze ich die Komponenten?

    Vielen Dank nochmal 🙂
    Freddy



  • f.sp schrieb:

    Hallo,
    wenn ich versuche das Programm zu compilieren:

    hey, das ist nur ein beispiel, wie man sowas mit sockets machen kann.
    der code ist für unix bzw. clones wie linux, den kannste nicht unverändert unter win zum laufen kriegen.
    aber berücksichtige auch den beitrag von akari
    🙂



  • Ich habe jetzt im Internet ein Programm mit Sockets gefunden, das auch bei mir funktioniert 😃

    /*********************************************************************
    
    Ein sehr(!!) Simpler Socket Server.
    -----------------------------------
    
    Beachtet das es nur ein Beispiel ist welches nicht ausprogrammiert ist.
    Es fehlen Anweisungen wie closesocket und WSACleanup.
    Ebenfalls wird hier auch nicht verhindert das mehrere Verbindungen
    hergestellt werden können.
    Aber zum demonstieren wie man eine Verbingung annimmt und Daten
    sendet und empfänget ist es recht geeignet.
    Eventuell hat es auch noch einige Fehler im Code..
    
    Testen könnt ihr ihn indem ihn auf '127.0.0.1 5432' eine telnet Verbindung
    herstellt (telnet 127.0.0.1 5432). Er wird euch erst "Hallo" sagen,
    und dann alle weiteren Daten welche ihr sendet mit "Ganz meine Meinung"
    beantworten. Simpel halt.
    
    by www.c-worker.ch
    
    **********************************************************************/
    
    #include <iostream.h>
    #include <stdlib.h>
    #include <windows.h>
    #include <winsock2.h>
    
    #define  SERVER_PORT             5999
    #define  RECV_BUF_MAXLEN         256
    #define  SEND_BUF_MAXLEN         256
    
    long WinsockStartup();
    
    int main()
    {
      long   rc;
    
      SOCKET sockListen;
      SOCKET sockConnected;
      SOCKADDR_IN addr;
      int addrlen = sizeof(addr);
    
      char sendBuf[SEND_BUF_MAXLEN+1];
      char recvBuf[RECV_BUF_MAXLEN+1];
    
      addr.sin_addr.s_addr = 0;
      addr.sin_family = AF_INET;
      addr.sin_port = htons(SERVER_PORT);
    
      rc = WinsockStartup();
      if (rc == SOCKET_ERROR)
      {
        cout << "Error: Winsock Startup failed: " << WSAGetLastError() << endl;
        return 0;
      }
      sockListen=socket(AF_INET,SOCK_STREAM,NULL);
      if (sockListen == INVALID_SOCKET)
      {
        cout << "Error: Cannot create Socket: " << WSAGetLastError() << endl;
        return 0;
      }
      rc = bind(sockListen, (SOCKADDR*)&addr, sizeof(addr));
      if (rc == SOCKET_ERROR)
      {
        cout << "Error: Cannot bind Socket: " << WSAGetLastError() << endl;
        return 0;
      }
      rc = listen(sockListen, NULL);
      if (rc == SOCKET_ERROR)
      {
        cout << "Error: Cannot listen: " << WSAGetLastError() << endl;
        return 0;
      }
      cout << "Waiting for a connection..." << endl;
      sockConnected=accept(sockListen, (SOCKADDR*)&addr, &addrlen);
    
      if (sockConnected == INVALID_SOCKET)
      {
        cout << "Error: Cannot accept connection: " << WSAGetLastError() << endl;
        return 0;
      }
      rc = send(sockConnected,"Hallo\0",6,NULL);
      if (rc == SOCKET_ERROR)
      {
        cout << "Error: Cannot send Data: " << WSAGetLastError() << endl;
        return 0;
      }
      cout << rc << " Bytes sent !" << endl;
      while (1)
      {
        rc = recv(sockConnected,recvBuf,RECV_BUF_MAXLEN,NULL);
        if (rc == SOCKET_ERROR)
        {
          cout << "Error: Cannot recv Data: " << WSAGetLastError() << endl;
          return 0;
        }
        if (rc == 0)
        {
          cout << "Other Host has closed the connection !" << endl;
          return 0;
        }
        recvBuf[rc] = '\0';
        cout << rc << " Bytes received: " << recvBuf << endl;
        rc = send(sockConnected,"Ganz meine Meinung\0",19,NULL);
        if (rc == SOCKET_ERROR)
        {
          cout << "Error: Cannot send Data: " << WSAGetLastError() << endl;
          return 0;
        }
        cout << rc << " Bytes sent !" << endl;
      }
    }
    
    long WinsockStartup()
    {
      long rc;
    
      WORD wVersionRequested;
      WSADATA wsaData;
      wVersionRequested = MAKEWORD(2, 1);
    
      rc = WSAStartup( wVersionRequested, &wsaData );
      return rc;
    }
    

    Wie muss ich das Programm verändern, dass es mit dem UDP-Protokoll funktioniert?
    Hab schon alles mögliche ausprobiert, aber wohl nicht das richtige... 😉

    Viele Grüße,
    Freddy



  • warum nimmst du nicht einfach den IdUDPServer?

    Beispiel:

    //bei ButtonClick oder Timer
      IdUDPServer1->Bindings->Items[0]->IP = DeineIP;
      IdUDPServer1->DefaultPort = DeinPort;
      IdUDPServer1->Active = true;
    
    //das OnUDPRead-Ereignis des IdUDPServers
    void __fastcall TForm1::IdUDPServer1UDPRead(TObject *Sender,
          TStream *AData, TIdSocketHandle *ABinding)
    {
    //Senderdaten ermitteln
    String ip = ABinding->PeerIP;
    int port = ABinding->PeerPort;
    
    //Inhalt der Sendung
    char *caBuffer;
    String stBuffer;
    
    int size = AData->Size;
    caBuffer = new char[size + 1];
    AData->Read(caBuffer, size);
    caBuffer[size] = '\0';
    stBuffer = (String)caBuffer;
    
    Memo1->Lines->Add(ip + " " + port + " " + stBuffer + "\r\n");
    Application->ProcessMessages();
    
    //Antwort zurücksenden
    String Antwort = "Alles ok";
    ABinding->SendTo(ip, port, Antwort .c_str(), Antwort .Length());
    delete[] caBuffer;
    }
    


  • Linnea schrieb:

    warum nimmst du nicht einfach den IdUDPServer?

    ich habe noch nie mit UDP in C++ gearbeitet, und mir wurde oben gesagt, dass ich das mit sockets machen müsste. 😉

    welche headerdatei muss ich einbinden um den "IdUDPServer" benutzen zu können?
    ich möchte das programm erstmal nur im konsolen-modus programmieren, ist das damit auch möglich, oder muss ich formulare verwenden?



  • TIdUDPServer ist Bestandteil des Indy-Paketes, das ab BCB6 mitgeliefert wird. Die Indy-Komponenten kapseln die Socket-Programmierung und stellen je nach Protokoll einfach(er) anzuwendende Schnittstellen zur Verfügung.

    Die Komponenten (das sind ja auch "nur" Klassen) lassen sich auch in Konsolenanwendungen einsetzen. Entweder du erzeugst die entsprechenden Instanzen zur Laufzeit, oder du bindest ein DataModule in dein Projekt ein, da kannst du die Komponenten dann auch zur Entwurfszeit drauf plazieren und konfigurieren.



  • beim BCB5 kann man das Indy-Packet selbst installieren, da gibts hier im Forum auch Tipps dazu



  • Ich find irgendwie im Forum nicht wie ich das Indy-Paket installieren soll...



  • Hallo

    Die Installation ist vollständig in der beiliegenden readme-Datei erklärt und steht auch online in der Indy-Knowledgebase.

    bis bald
    akari


Anmelden zum Antworten