Winsock problem
-
Hallo Community!
Erstmal entschuldigug wenn ich den Beitrag im falschen Forum poste.
Nun zu meinem Problem. Ich habe eine Server und eine Client datei geschrieben(eigentlich übernommen aus dem Buch C++ von A bis Z).Nun ist mein Problem das ich die Server datei normal starten kann und die Client datei auch doch die Client datei schließt sich sofort wieder. Hier der Quellcode aus der 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; }und noch die Socket.cpp datei die ich dazu linken soll:
// socket.cpp #include <cstdlib> #include <winsock.h> #include <io.h> #include <iostream> #include "socket.h" using namespace std; // Konstruktor Socket::Socket() : m_sock(0) { // Winsock.DLL Initialisieren WORD wVersionRequested; WSADATA wsaData; wVersionRequested = MAKEWORD (1, 1); if (WSAStartup (wVersionRequested, &wsaData) != 0) { cout << "Fehler beim Initialisieren von Winsock" << endl; exit(1); } } // Destruktor Socket::~Socket() { if ( is_valid() ) ::closesocket ( 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); } 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, ( int * ) &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( host.c_str() )) != 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( port ); 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 != SOCKET_ERROR ) { 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 == SOCKET_ERROR) { 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, &len ); if (n == SOCKET_ERROR){ cout << "Fehler bei recvfrom()" << endl; exit(1); return 0; } else { s = buf; return n; } } // Winsock.dll freigeben void Socket::cleanup() const { /* Cleanup Winsock */ WSACleanup(); } // Socket schließen und Winsock.dll freigeben bool Socket::close() const { closesocket(m_sock); cleanup(); return true; }Ich weiss nicht ob die Header datei auch eine rolle spielt aber hier:
/* socket.h für MS-Windows */ #ifndef SOCKET_H_ #define SOCKET_H_ #include <string> #include <winsock.h> #include <io.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
-
Wie startest du den Client?
-
moin354 schrieb:
Nun zu meinem Problem. Ich habe eine Server und eine Client datei geschrieben(eigentlich übernommen aus dem Buch C++ von A bis Z).
Also hast du 2 Probleme. Loese erstmal das groessere und schmeiss das Buch weg.
-
Danke für die Antworten,
mir ist schon oft gesagt worden das das Buch nicht gut ist.Ich benutze es auch hauptsächlich zum nachschlagen. Ich weiss jetzt nicht wie das gemeint ist mit dem starten aber als erstes starte ich den server mit F5 und dann den Client mit F5.
-
moin354 schrieb:
wie das gemeint ist mit dem starten aber als erstes starte ich den server mit F5 und dann den Client mit F5.
Starte Deine Konsolenprogramme aus einer Konsole, dann schließt die sich auch nicht bei Programmende.
-
So hab ich gemacht nun steht in der Konsole der Pfad wo das Programm ist und Serveradresse. aber ich kann keine befehle an den Server senden :(.
-
Du startest den client mit
client localhostDann sollte "Nachricht an den Server: " erscheinen.
Dann kannst du was eingeben und mit der Entertaste abschicken.Danach ist der Client beendet.
-
tut mir leid aber ich weiss nicht wie ich die datei mit client localhost starte.
-
moin354 schrieb:
tut mir leid aber ich weiss nicht wie ich die datei mit client localhost starte.

In dem Konsolenfenster eintippen.Ich weiß nicht wie dein Clientprogramm heißt. Wenn es nicht
clientheißt, musst du natürlich den entsprechenden Namen eingeben.
Auch sollte das aktuelle Verzeichnis im Konsolenfenster, das Verzeichnis mit dem Clientprogramm sein.
-
Es hat funktioniert :DDD Danke und tut mir leid ich hatte das gerade falsch verstanden ^^. kann ich das auch über die exe richtig hinkriegen sodass ich das nicht über die konsole machen muss? Und wie funktioniert es auf Ubuntu?
-
Du rufst in der Konsole die Exe auf.
Du musst halt irgendwie den Servernamen/-adresse übergeben.Das kann man auch meist in der IDE bei den Projekteigenschaften machen.
Dann kannst du das über F5 starten.Später kannst du das mit einer Verknüpfung machen.
Den Servernamen fest im Programm zu verdrahten ist blöd, da du dann den Client oder Server nicht mehr auf beliebigen Rechnern starten kannst.
Als Programmierer solltest du dich aber schon mit der Konsole auskennen.