Winsock auf Ubuntu



  • Ach so ja, für Ubuntu muss der Code natürlich angepasst werden. 1. musst du keine win(dows) Sockets lib linken, und zweitens brauchst du andere Header. (Und WSAStartup etc. gibt's da auch nicht.)



  • tut mir leid wenn das so nicht stimmt aber in meinem buch steht das so 😞 kann mir jemand den quellcode so überarbeiten das es passt? Ich würde es ja selber machen aber so viel erfahrung habe ich noch nicht.



  • .. welchen Quellcode?



  • echo_client datei:

    // echo_client.cpp
    #include "socket.h"
    #include <string>
    #include <iostream>
    #include <cstdlib>
    using namespace std;
    
    int main (int argc, char *argv[]) {
       if( argc < 2 ){
          cout << "Usage: " << *argv << " ServerAdresse\n";
          exit(1);
       }
       Socket sock;
       sock.create();
       // Adresse des Servers
       string argv_1 = argv[1];
       // Mit dem Server auf Port 15000 verbinden
       sock.connect( argv_1, 15000 );
       cout << "Nachricht an den Server: ";
       string s;
       getline(cin, s, '\n' );
       sock.send( s );
       sock.close();
       return 0;
    }
    

    socket datei:

    // socket.cpp
    #include <cstdlib>
    #include <iostream>
    #include <cstring>
    #include "socket.h"
    using namespace std;
    
    // Konstruktor
    Socket::Socket() : m_sock(0) { }
    
    // Destruktor
    Socket::~Socket() {
       if ( is_valid() )
          ::close( m_sock );
    }
    
    // Erzeugt das Socket  - TCP
    bool Socket::create() {
       m_sock = ::socket(AF_INET,SOCK_STREAM,0);
       if (m_sock < 0) {
          cout << "Fehler beim Anlegen eines Socket" << endl;
          exit(1);
       }
       int y=1;
       // Mehr dazu siehe Hinweis am Ende
       setsockopt( m_sock, SOL_SOCKET,
                   SO_REUSEADDR, &y, sizeof(int));
       return true;
    }
    
    // Erzeugt das Socket  - UDP
    bool Socket::UDP_create() {
       m_sock = ::socket(AF_INET,SOCK_DGRAM,0);
       if (m_sock < 0) {
          cout << "Fehler beim Anlegen eines Socket" << endl;
          exit(1);
       }
    }
    
    // Erzeugt die Bindung an die Serveradresse
    // - genauer an einen bestimmten Port
    bool Socket::bind( const int port ) {
       if ( ! is_valid() ) {
          return false;
       }
       m_addr.sin_family = AF_INET;
       m_addr.sin_addr.s_addr = INADDR_ANY;
       m_addr.sin_port = htons ( port );
    
       int bind_return = ::bind ( m_sock,
          ( struct sockaddr * ) &m_addr, sizeof ( m_addr ) );
       if ( bind_return == -1 ) {
          return false;
       }
       return true;
    }
    
    // Teile dem Socket mit, dass Verbindungswünsche
    // von Clients entgegengenommen werden
    bool Socket::listen() const {
       if ( ! is_valid() ) {
          return false;
       }
       int listen_return = ::listen ( m_sock, MAXCONNECTIONS );
       if ( listen_return == -1 ) {
          return false;
       }
      return true;
    }
    
    // Bearbeite die Verbindungswünsche von Clients
    // Der Aufruf von accept() blockiert solange,
    // bis ein Client Verbindung aufnimmt
    bool Socket::accept ( Socket& new_socket ) const {
       int addr_length = sizeof ( m_addr );
       new_socket.m_sock = ::accept( m_sock,
          ( sockaddr * ) &m_addr, ( socklen_t * ) &addr_length );
       if ( new_socket.m_sock <= 0 )
          return false;
       else
          return true;
    }
    
    // Baut die Verbindung zum Server auf
    bool Socket::connect( const string host, const int port ) {
       if ( ! is_valid() )
          return false;
       struct hostent *host_info;
       unsigned long addr;
       memset( &m_addr, 0, sizeof (m_addr));
       if ((addr = inet_addr( meine ip )) != INADDR_NONE) {
           /* argv[1] ist eine numerische IP-Adresse */
           memcpy( (char *)&m_addr.sin_addr,
                   &addr, sizeof(addr));
       }
       else {
           /* Für den Fall der Fälle: Wandle den Servernamen  *
            * bspw. "localhost" in eine IP-Adresse um         */
           host_info = gethostbyname( host.c_str() );
           if (NULL == host_info) {
              cout << "Unbekannter Server" << endl;
              exit(1);
           }
           memcpy( (char *)&m_addr.sin_addr, host_info->h_addr,
                    host_info->h_length);
       }
       m_addr.sin_family = AF_INET;
       m_addr.sin_port = htons( 15000 );
    
       int status = ::connect ( m_sock,
          ( sockaddr * ) &m_addr, sizeof ( m_addr ) );
    
      if ( status == 0 )
        return true;
      else
        return false;
    }
    
    // Daten versenden via TCP
    bool Socket::send( const string s ) const {
       int status = ::send ( m_sock, s.c_str(), s.size(),  0 );
       if ( status == -1 ) {
          return false;
       }
       else {
          return true;
       }
    }
    
    // Daten empfangen via TCP
    int Socket::recv ( string& s ) const {
      char buf [ MAXRECV + 1 ];
      s = "";
      memset ( buf, 0, MAXRECV + 1 );
    
      int status = ::recv ( m_sock, buf, MAXRECV, 0 );
      if ( status > 0 || status != -1 ) {
         s = buf;
         return status;
      }
      else {
         cout << "Fehler in Socket::recv" << endl;
         exit(1);
         return 0;
      }
    }
    
    // Daten versenden via UDP
    bool Socket::UDP_send( const string addr, const string s, const int port ) const {
       struct sockaddr_in addr_sento;
       struct hostent *h;
       int rc;
    
       h = gethostbyname(addr.c_str());
       if (h == NULL) {
          cout << "Unbekannter Host?" << endl;
          exit(1);
       }
       addr_sento.sin_family = h->h_addrtype;
       memcpy ( (char *) &addr_sento.sin_addr.s_addr,
                h->h_addr_list[0], h->h_length);
       addr_sento.sin_port = htons (port);
       rc = sendto( m_sock, s.c_str(), s.size(), 0,
                     (struct sockaddr *) &addr_sento,
                      sizeof (addr_sento));
       if (rc == -1) {
          cout << "Konnte Daten nicht senden - sendto()"
               << endl;
          exit(1);
       }
       return true;
    }
    
    // Daten empfangen vie UDP
    int Socket::UDP_recv( string& s ) const {
       struct sockaddr_in addr_recvfrom;
       int len, n;
       char buf [ MAXRECV + 1 ];
       s = "";
       memset ( buf, 0, MAXRECV + 1 );
       len = sizeof (addr_recvfrom);
       n = recvfrom ( m_sock, buf, MAXRECV, 0,
                      (struct sockaddr *) &addr_recvfrom,
                      ( socklen_t * )&len );
       if (n == -1){
          cout << "Fehler bei recvfrom()" << endl;
          exit(1);
          return 0;
       }
       else {
          s = buf;
          return n;
       }
    }
    
    // Aus Portabiltätsgründen vorhanden
    void Socket::cleanup() const { }
    
    // Socket schließen
    bool Socket::close() const {
       ::close(m_sock);
       cleanup();
       return true;
    }
    

    und socket.h:

    /* socket.h für MS-Windows */
    #ifndef SOCKET_H_
    #define SOCKET_H_
    #include <string>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <netdb.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    
    using namespace std;
    
    // Max. Anzahl Verbindungen
    const int MAXCONNECTIONS = 5;
    // Max. Anzahl an Daten die aufeinmal empfangen werden
    const int MAXRECV = 1024;
    
    // Die Klasse Socket
    class Socket {
       private:
       // Socketnummer (Socket-Deskriptor)           
       int m_sock; 
       // Struktur sockaddr_in
       sockaddr_in m_addr;
    
       public:
       // Konstruktor
       Socket();
       // virtueller Destruktor
       virtual ~Socket();
    
       // Socket erstellen - TCP
       bool create();
       // Socket erstellen - UDP
       bool UDP_create();
       bool bind( const int port );
       bool listen() const;
       bool accept( Socket& ) const;
       bool connect ( const string host, const int port );
       // Datenübertragung - TCP
       bool send ( const string ) const;
       int recv ( string& ) const;
       // Datenübertragung - UDP
       bool UDP_send( const string, const string,
                      const int port ) const;
       int UDP_recv( string& ) const;
       // Socket schließen
       bool close() const;
       // WSAcleanup()
       void cleanup() const;
       bool is_valid() const { return m_sock != -1; }
    };
    #endif
    


  • Abgesehen von den gefühlt 10k Designfehlern und der Tatsache, dass auf

    /* socket.h für MS-Windows */
    

    erstmal eine ganze Reihe von Unix Headern folgen, sollte das laufen. Was bekommst du denn für eine Fehlermeldung beim Kompilieren auf Ubuntu?



  • Hallo

    Es funktioniert wenn ich es einfach ausführe aber ich mjuss es ja über localhost ausführen und dann steht da halt nachricht an den server: dann geb ich da halt was ein aber es kommt nichts dort an 😞



  • Was soll denn Zeile 91 machen? Sicher, dass das so korrekt ist?



  • cooky451 schrieb:

    Was soll denn Zeile 91 machen? Sicher, dass das so korrekt ist?

    ich hab die komplette datei aus dem buch also müsste sie ja korrekt sein.



  • Abgeschrieben? Oder von einer CD kopiert? Abgesehen davon macht die Zeile nicht deshalb mehr Sinn, weil sie aus dem Buch ist. Schon komisch. - Ah, jetzt hast du es editiert. Sollte also deine IP sein. Ist dir klar, dass das in der Klammer eine Zuweisung und kein Vergleich ist? Kommentier den ganzen if-Block am besten mal aus zum Testen.



  • Ich habe es von der cd kopiert und in dem buch steht das ich meine ip dort einfügen soll. Ich probiere ihn jetzt rauszunehmen. So habs jetzt rausgenommen und bekomme folgende fehler:

    /media/moin354/B4EA-C462/socket.cpp|97|Warnung: »/*« innerhalb des Kommentars [-Wcomment]|
    /media/moin354/B4EA-C462/socket.cpp|89|Warnung: Variable »addr« wird nicht verwendet [-Wunused-variable]|
    /media/moin354/B4EA-C462/socket.cpp|107|Fehler: »m_addr« bezeichnet keinen Typ|
    /media/moin354/B4EA-C462/socket.cpp|108|Fehler: »m_addr« bezeichnet keinen Typ|
    /media/moin354/B4EA-C462/socket.cpp|110|Fehler: »m_sock« wurde in diesem Gültigkeitsbereich nicht definiert|
    /media/moin354/B4EA-C462/socket.cpp|111|Fehler: »m_addr« wurde in diesem Gültigkeitsbereich nicht definiert|
    /media/moin354/B4EA-C462/socket.cpp|111|Fehler: »m_addr« wurde in diesem Gültigkeitsbereich nicht definiert|
    /media/moin354/B4EA-C462/socket.cpp|113|Fehler: expected unqualified-id before »if«|
    /media/moin354/B4EA-C462/socket.cpp|115|Fehler: expected unqualified-id before »else«|
    /media/moin354/B4EA-C462/socket.cpp|117|Fehler: expected declaration before »}« token|
    /media/moin354/B4EA-C462/socket.cpp|106|Warnung: Kontrollfluss erreicht Ende von Nicht-void-Funktion [-Wreturn-type]|
    /media/moin354/B4EA-C462/socket.cpp|38|Warnung: Kontrollfluss erreicht Ende von Nicht-void-Funktion [-Wreturn-type]|
    ||=== Build finished: 12 errors, 0 warnings ===|



  • @ cooky451
    Zeile 91 ist durchaus so gemeint und auch richtig.



  • @TE Dann hast du beim Auskommentieren wohl was falsch gemacht.

    Athar schrieb:

    @ cooky451
    Zeile 91 ist durchaus so gemeint und auch richtig.

    😕 Aber der else Pfad wird doch nie ausgeführt?



  • Wenn du mehr über sockets erfahren willst, kannst du dir ja mal die Seiten http://www.zotteljedi.de/socket-tipps/index.html ansehen.



  • oder hat vielleicht jemand eine funktionierende socket datei für windows und linux die ich zur übung nehmen könnte? Denn dieses Buch fängt langsam an mich ziemlich aufzuregen... 😡


Anmelden zum Antworten