Zum Inhalt springen

Socketprogrammierung in C


ChrisP

Empfohlene Beiträge

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

Link zu diesem Kommentar
Auf anderen Seiten teilen

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; }

Link zu diesem Kommentar
Auf anderen Seiten teilen

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.
Link zu diesem Kommentar
Auf anderen Seiten teilen

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.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...