Problem mit Sockets
-
hi,
bin gerade dabei, mich mit Sockets zu beschäftigen. Habe ein Beispiel, bei dem ich über das UDP-Protokoll Daten bzw. einfache Strings austausche. Ich starte also den Sever, dann über Kommandozeilen-Argumente den Client und will dann Strings an den Server schicken, der diesen ausgibt und eine Meldung an den Client zurückgibt, dass er den Text erhalten hat.
Problem ist nur, dass immer die Exception: Konnte Daten nicht senden ausgelöst wird und ich aber nicht versteh', wo der Fehler liegen soll.
Hier der Code (in Visual Studio 2005 Pro erstellt):
socket.h
#ifndef _SOCKET_H #define _SOCKET_H #include <iostream> #include <Windows.h> #include <WinSock.h> #include <string> #include <io.h> using namespace std; // max. Anzahl Verbindungen const int MAXCONNECTIONS = 5; // max. Anzahl Daten, die auf einmal empfangen werden const int MAXRECV = 1024; class Socket { private: // Socket-Deskriptor int m_sock; // Struktur sockaddr_in sockaddr_in m_addr; public: Socket(); ~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; }; class SockExcept { private: string except; public: SockExcept(string s) : except(s) {}; ~SockExcept() {}; string get_SockExcept() {return except;}; }; #endifsocket.cpp
#include <iostream> #include <Windows.h> #include <WinSock.h> #include <string> #include <cstdlib> #include "socket.h" using namespace std; Socket::Socket() : m_sock(0) { // WinSock.dll initialisieren WORD wVersionRequested; WSADATA wsaData; wVersionRequested = MAKEWORD(1, 1); if (WSAStartup(wVersionRequested, &wsaData) != 0) { throw SockExcept("Fehler beim Initialisieren von Winsock\n"); } } Socket::~Socket() { if (is_valid()) ::closesocket(m_sock); } bool Socket::is_valid() const { return m_sock != -1; } // erzeugt das Socket-TCP bool Socket::create() { m_sock = (int)::socket(AF_INET, SOCK_STREAM, 0); if (m_sock < 0) { throw SockExcept("Fehler beim Anlegen eines Socket\n"); } return true; } // erzeugt das Socket-UDP bool Socket::UDP_create() { m_sock = (int)::socket(AF_INET, SOCK_DGRAM, 0); if (m_sock < 0) { throw SockExcept("Fehler beim Anlegen eines Socket\n"); exit(1); } return true; } // Bindung an 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; } // Socket mitteilen, 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; } // Verbindungswünsche von Clients bearbeiten // Aufruf von accept() blockiert so lange, bis ein Client Verbindung aufnimmt bool Socket::accept(Socket& new_Socket) const { int addr_length = sizeof(m_addr); new_Socket.m_sock = (int)::accept(m_sock, (sockaddr*) &m_addr, (int*) &addr_length); if (new_Socket.m_sock <= 0) return false; else return true; } // baut 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 { // Servernamen (z.B. localhost) in IP-Adresse umwandeln host_info = gethostbyname(host.c_str()); if (NULL == host_info) { throw SockExcept("Unbekannter Server\n"); 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 std::string s) const { int status = ::send(m_sock, s.c_str(), (int)s.size(), 0); if (status == -1) return false; else return true; } // Daten empfangen via TCP int Socket::recv(std::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 { throw SockExcept("Fehler in Socket::recv\n"); 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) { throw SockExcept("Unbekannter Host\n"); 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(), (int)s.size(), 0, (struct sockaddr *) &addr_sento, sizeof(addr_sento)); if (rc == SOCKET_ERROR) { throw SockExcept("Konnte Daten nicht senden - sendto()\n"); exit(1); } return true; } // Daten empfangen via UDP int Socket::UDP_recv(std::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) { throw SockExcept("Fehler bei recvfrom()\n"); exit(1); return 0; } else { s = buf; return n; } } // Winsock.dll freigeben void Socket::cleanup() const { WSACleanup(); } // Socket schließen und Winsock.dll freigeben bool Socket::close() const { closesocket(m_sock); cleanup(); return true; }Main.cpp (vom Server
#include <iostream> #include <string> #include "socket.h" using namespace std; int main() { try { Socket server; server.UDP_create(); server.bind(14000); cout << "Server wartet auf Daten..." << endl; try { while (true) { string s; server.UDP_recv(s); cout << "Daten erhalten: " << s << endl; } } catch (SockExcept &) {} } catch (SockExcept &e) { cout << "Exception: " << e.get_SockExcept() << endl; } cin.get(); return 0; }client.cpp
#include <iostream> #include <string> #include "socket.h" using namespace std; int main(int argc, char *argv[]) { if (argc < 3) { cout << "Usage: " << argv[0] << " <server> <string>" << endl; //exit(1); } try { Socket client; client.UDP_create(); client.bind(14000); string argv_1 = argv[1]; string argv_2 = argv[2]; client.UDP_send(argv_1, argv_2, 14000); } catch (SockExcept &e) { cout << "Exception: " << e.get_SockExcept() << endl; } return 0; }Vllt hab ihr noch weitere Hinweise zu dem Code, was vllt schlecht gelöst ist...
Hoffe, ihr könnt mir helfen und habt verstanden, was ich meine
.thx im voraus
mfg R3dNeXX