ChrisP Geschrieben 28. Juli 2005 Geschrieben 28. Juli 2005 Hallo, ich habe einen Server und einen Client in C geschrieben. Der Client kann sich auch zum Server connecten und der Server gibt auch beim ersten Senden das Gesendete aus. Wenn der Client danach wieder Daten sendet, kommt am Server nichts mehr an. Die Funktion accept() scheint keine Verbindung mehr zu akzeptieren. Hat jemand eine Idee? Gruß Chr Zitieren
carstenj Geschrieben 28. Juli 2005 Geschrieben 28. Juli 2005 Hallo, sowas ist ohne Code wohl ziemlich unmöglich zu klären. Zitieren
ChrisP Geschrieben 28. Juli 2005 Autor Geschrieben 28. Juli 2005 Stimmt, das macht natürlich Sinn! Client: /* client.cpp */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <errno.h> /* Headerfiles für Windows */ #include <winsock.h> #include <io.h> #include <iostream.h> #define PORT 1234 #define RCVBUFSIZE 8192 /* Funktion gibt aufgetrenene Fehler aus und * beendet die Anwendung */ static void error_exit(char *errorMessage) { fprintf(stderr,"%s: %d\n", errorMessage, WSAGetLastError()); exit(EXIT_FAILURE); } void send_recv(SOCKET socket, char* echo_string) { int echo_len; echo_len = strlen(echo_string); /* Denn String inskl. Nullterminator an den Server senden */ if (send(socket, echo_string, echo_len, 0) != echo_len){ error_exit("send() hat eine unterschiedliche Anzahl von Bytes versendet, als erwartet."); } /*int bytesRecv = SOCKET_ERROR; char recvbuf[32] = ""; while( bytesRecv == SOCKET_ERROR ) { bytesRecv = recv( socket, recvbuf, 32, 0 ); printf("bytesRecv: %d\n",bytesRecv); if ( bytesRecv == 0 || bytesRecv == WSAECONNRESET ) { printf( "Connection Closed.\n"); break; } if (bytesRecv < 0) return; printf("Client empfängt: %s\n",recvbuf); } printf("ende send_recv()\n"); */ } int main() { struct sockaddr_in server; struct hostent *host_info; unsigned long addr; SOCKET sock; char *echo_string; char *recv_string; char *target_host; char *output_string; int option; //int echo_len, recv_len; /* Initialisiere TCP für Windows ("winsock") */ WORD wVersionRequested; WSADATA wsaData; wVersionRequested = MAKEWORD (1, 1); if (WSAStartup (wVersionRequested, &wsaData) != 0) error_exit( "Fehler beim Initialisieren von Winsock"); else printf("Winsock initialisiert\n"); /* Erzeuge das Socket */ sock = socket( AF_INET, SOCK_STREAM, 0 ); if (sock < 0) error_exit( "Fehler beim Anlegen eines Sockets"); int i; i=0; for(; { cout << "Optionen: \n"; cout << "(1) String senden\n"; cout << "(2) Client beenden\n"; cin >> option; switch(option){ case 1: /* Erzeuge die Socketadresse des Servers * Sie besteht aus Typ, IP-Adresse und Portnummer */ cout << "Geben Sie einen Zielhost ein: "; cin >> target_host; cout << "Geben Sie einen Ausgabe-String ein: "; cin >> echo_string; memset( &server, 0, sizeof (server)); if ((addr = inet_addr(target_host)) != INADDR_NONE) { /* target_host ist eine numerische IP-Adresse */ memcpy( (char *)&server.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(target_host); if (NULL == host_info) error_exit("Unbekannter Server"); /* Server-IP-Adresse */ memcpy( (char *)&server.sin_addr, host_info->h_addr, host_info->h_length ); } /* IPv4-Verbindung */ server.sin_family = AF_INET; /* Portnummer */ server.sin_port = htons( PORT ); printf("vor connect()\n"); /* Baue die Verbindung zum Server auf */ if(i==0){ if(connect(sock,(struct sockaddr*)&server,sizeof(server)) <0) { error_exit("Kann keine Verbindung zum Server herstellen"); } i = i+1; } send_recv(sock,echo_string); /* Denn String inskl. Nullterminator an den Server senden if (send(sock, echo_string, echo_len, 0) != echo_len) error_exit("send() hat eine unterschiedliche Anzahl von Bytes versendet, als erwartet."); */ /*char recvbuf[32]; int bytesRecv = SOCKET_ERROR; while(bytesRecv != SOCKET_ERROR) { if((bytesRecv = recv(sock, recvbuf, 32, 0)) < 0) error_exit("recv() fehlgeschlagen.\n"); } cout << "bytesRecv: " << bytesRecv; */ break; case 2: return(EXIT_SUCCESS); default: cout << "Falsche Eingabe\n"; break; } } /* Schließe Verbindung und Socket */ closesocket(sock); /* Cleanup Winsock */ WSACleanup(); return EXIT_SUCCESS; }[/code] Server: [code]/* server.cpp */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <errno.h> #include <time.h> /* Headerfiles für Windows */ #include <winsock.h> #include <io.h> #include <iostream.h> /* Portnummer */ #define PORT 1234 /* Puffer für eingehende Nachrichten */ #define RCVBUFSIZE 1024 // maximale Anzahl der Verbindungen #define MAX_LISTENER 5 // Prototypen static void echo(SOCKET); static void error_exit(char *errorMessage); void init_winsock(void); SOCKET create_socket(void); /* Funktion gibt Daten vom Client auf dem stdout aus, * welche dieser mit der Kommandozeile übergibt */ static void echo(SOCKET client_socket) { char echo_buffer[RCVBUFSIZE]; int recv_size; time_t zeit; //int bytesSent; //char sendbuf[32] = "Server sendet"; if((recv_size = recv(client_socket, echo_buffer, RCVBUFSIZE,0)) < 0) error_exit("Fehler bei recv()"); echo_buffer[recv_size] = '\0'; time(&zeit); printf("Server empfängt: %s \t%s",echo_buffer, ctime(&zeit)); /*printf("vor send()\n"); bytesSent = send( client_socket, sendbuf, strlen(sendbuf), 0 ); //printf("Ende echo()\n"); */ } /* Funktion gibt aufgetrenene Fehler aus und * beendet die Anwendung */ static void error_exit(char *error_message) { fprintf(stderr,"%s: %d\n", error_message, WSAGetLastError()); exit(EXIT_FAILURE); } void init_winsock() { /* Initialisiere TCP für Windows ("winsock") */ WORD wVersionRequested; WSADATA wsaData; wVersionRequested = MAKEWORD (1, 1); if (WSAStartup (wVersionRequested, &wsaData) != 0) error_exit( "Fehler beim Initialisieren von Winsock"); else printf("Winsock initialisiert\n"); } SOCKET create_socket() { SOCKET sock; /* Erzeuge das Socket */ sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (sock < 0) error_exit("Fehler beim Anlegen eines Socket"); return sock; } int main() { struct sockaddr_in server; //client SOCKET OrigSocket, AcceptSocket; int len, echo_len; char *echo_string; init_winsock(); OrigSocket = create_socket(); /* Erzeuge die Socketadresse des Servers */ memset( &server, 0, sizeof (server)); /* IPv4-Verbindung */ server.sin_family = AF_INET; /* INADDR_ANY Jede IP-Adresse annehmen */ server.sin_addr.s_addr = htonl(INADDR_ANY); /* Portnummer */ server.sin_port = htons(PORT); /* Erzeuge die Bindung an die Serveradresse * (genauer an einen bestimmten Port) */ if(bind(OrigSocket,(struct sockaddr*)&server, sizeof( server)) < 0) error_exit("Kann das Socket nicht \"binden\""); // wieder einfügen /* Bearbeite die Verbindungswünsche von Clients * in einer Endlosschleife * Der Aufruf von accept() blockiert solange, * bis ein Client Verbindung aufnimmt */ int acc = 0; for (; { /* Teile dem Socket mit, dass Verbindungswünsche * von Clients entgegengenommen werden */ if(listen(OrigSocket, MAX_LISTENER) == -1 ) error_exit("Fehler bei listen"); //len = sizeof(server); //client printf( "Waiting for a client to connect...\n" ); AcceptSocket = SOCKET_ERROR; while ( AcceptSocket == SOCKET_ERROR ) { AcceptSocket = accept(OrigSocket,NULL,NULL); acc++; } printf( "Client Connected: accept: %d.\n",acc); echo(AcceptSocket); } /* Schließe die Verbindung */ closesocket(OrigSocket); closesocket(AcceptSocket); WSACleanup(); return EXIT_SUCCESS; } Zitieren
Klotzkopp Geschrieben 29. Juli 2005 Geschrieben 29. Juli 2005 Die Funktion accept() scheint keine Verbindung mehr zu akzeptieren. Hat jemand eine Idee?Der Client baut keine zweite Verbindung auf. Du hast ja dafür gesorgt, dass connect nur einmal aufgerufen wird. Der Client schickt alle Daten über denselben Socket raus, der Server erwartet nach jedem recv/send-Paar einen neuen Verbindungsaufbau. Das kann nicht funktionieren. Zitieren
ChrisP Geschrieben 29. Juli 2005 Autor Geschrieben 29. Juli 2005 Danke. Klappt jetzt. Also kann ich bei einem Socket nur einmal send und recv aufrufen? Zitieren
Guybrush Threepwood Geschrieben 29. Juli 2005 Geschrieben 29. Juli 2005 Nein, aber du hast ja jedesmal in deiner Schleife auf einen Verbindungsaufbau gewartet anstatt die eine Verbindung die ganze Zeit zu benutzen. Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.