Netzwerkkommunikation mit Threads



  • Hallo,

    ich brauche in einem Programm die Möglichkeit der Netzwerkkommunikation.
    Diese soll aber nicht sequentiell ablaufen, sondern jeder soll zu jedem Zeitpunkt etwas schicken können, also nicht erst A, dann B, dann A usw usw.

    Was ich mir also überlegt habe, ist dies in Posix Threads aufzuteilen. Einen Thread der immer nur hört und ein anderer welche andere anfallenden Arbeiten ausführt. Das Problem ist: Die Funktion accept blockiert in diesem Fall nicht wie wenn es nur einen Thread gibt. Ein Verbindungsaufbau ist also nicht möglich.

    Habt ihr Ideen oder Lösungen die ich mir ansehen kann?

    Danke

    mfg naja



  • Du brauchst einen Thread der auf Verbindungen wartet und dann für jede angenommene Verbindung einen weiteren Thread.

    In der Konsole lässt sich sowas aber schlecht umsetzen, da du nur schlecht gleichzeitig Eingaben und Ausgaben machen kannst. In dem Fall wäre eine GUI angebracht.

    Vergiss die Threadsynchronisation nicht.



  • hi,

    ne gui ist leider unangebracht, da die kommunikation nur zu zeiten der entwicklung von menschen benutzt wird.

    aber: sobald ich doch den aufruf von accept in einem Thread platziere blockiert der aufruf nicht. zumindest bei meinem code. oder ist hier ein grober fehler drin?

    static void* listeningThread(void *arg) {
    	char* msg = (char*)arg;
    	int sock1, concrsock;
    	struct sockaddr_in addr;
    	char* buffer = malloc(BUFFERSIZE);
    	const int y = 1;
    	socklen_t addrlen;
    
    	//printf("%s\n", **msg);
    
    	printf("Start des ListeningThreads\n");
    
    	if(sock1 = socket(AF_INET, SOCK_STREAM,0) > 0) {
    		printf("Socket zum Empfangen erfolgreich angelegt\n");
    	}
    
    	setsockopt(sock1, SOL_SOCKET, SO_REUSEADDR, &y, sizeof(int));
    
    	addr.sin_port = htons(15000);
    	addr.sin_family = AF_INET;
    	addr.sin_addr.s_addr = INADDR_ANY;
    
    	bind(sock1, (struct sockaddr*)&addr, sizeof(addr));
    	listen(sock1, 10);
    	addrlen = sizeof(struct sockaddr_in);
    
    	while(1) {
    		printf("ist am warten....\n");
    		if( (concrsock = accept(sock1, (struct sockaddr*)&addr, &addrlen)) > 0)
    			printf("Erfolgreich einen Klienten verbunden\n");
    		printf("warten vorbei....\n");
    		buffer = "Ich lebe\0";
    		send(concrsock, buffer, strlen(buffer), 0);
    	}
    
    	printf("Listening zu Ende");
    
    }
    


  • naja schrieb:

    Das Problem ist: Die Funktion accept blockiert in diesem Fall nicht wie wenn es nur einen Thread gibt. Ein Verbindungsaufbau ist also nicht möglich.

    Hihi.
    Nö.
    Wie kommst du darauf?
    Klar blockiert accept() auch wenn man 100 Threads laufen hat.
    So lange du den Listen-Socket nicht auf non-blocking schaltest, ändert sich daran nix.
    Selbst wenn die 100 Threads die sonst noch laufen auch alle mit Socket-Funktionen rummachen ändert sich daran nix.

    Eine einfache Server-Schleife ala

    while (!stop_server)
    {
        new_socket = accept(listen_socket);
        start_thread(handle_connection, new_socket);
    }
    

    funktioniert wunderbar.



  • hi,

    dann entschuldige meine unwissenheit.

    kannst du mir auch sagen woher diese ausgabe kommt?

    [code}
    ...
    warten vorbei....
    ist am warten....
    warten vorbei....
    ist am warten....
    warten vorbei....
    ist am warten....
    warten vorbei....
    ist am warten....
    warten vorbei....
    ist am warten....
    warten vorbei....
    ist am warten....
    warten vorbei....
    ist am warten....
    warten vorbei....
    ...
    [/code]

    warten vorbei dürfte ja gar nicht vorkommen, wenn accept auf ein connect warten würde.

    mfg naja



  • Vielleicht solltest du den Socket nach dem Senden wieder schließen. Er wird ja offensichtlich danach nicht mehr gebraucht. Woher die Ausgabe kommt kann man dir aber vermutlich nicht sagen. Eventuell hast du doch mehrere Threads, die sich in die Quere kommen oder whatever. Bau doch mal ein kompilierbares Minibeispiel mit dem Problem zusammen.



  • morgen,

    /*
     * router.c
     *
     *  Created on: 20.06.2010
     *      Author: andreas
     */
    
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <pthread.h>
    #define BUFFERSIZE 1024
    
    static void* listeningThread(void *arg) {
    	char* msg = (char*)arg;
    	int sock1, concrsock;
    	struct sockaddr_in addr;
    	char* buffer = malloc(BUFFERSIZE);
    	const int y = 1;
    	socklen_t addrlen;
    
    	//printf("%s\n", **msg);
    
    	printf("Start des ListeningThreads\n");
    
    	if(sock1 = socket(AF_INET, SOCK_STREAM,0) > 0) {
    		printf("Socket zum Empfangen erfolgreich angelegt\n");
    	}
    
    	setsockopt(sock1, SOL_SOCKET, SO_REUSEADDR, &y, sizeof(int));
    
    	addr.sin_port = htons(15000);
    	addr.sin_family = AF_INET;
    	addr.sin_addr.s_addr = INADDR_ANY;
    
    	bind(sock1, (struct sockaddr*)&addr, sizeof(addr));
    	listen(sock1, 10);
    	addrlen = sizeof(struct sockaddr_in);
    
    	while(1) {
    		printf("ist am warten....\n");
    		if( (concrsock = accept(sock1, (struct sockaddr*)&addr, &addrlen)) > 0)
    			printf("Erfolgreich einen Klienten verbunden\n");
    		printf("warten vorbei....\n");
    		buffer = "Ich lebe\0";
    		send(concrsock, buffer, strlen(buffer), 0);
    	}
    
    	printf("Listening zu Ende");
    
    }
    
    static void* sendingThread(void* arg) {
    	int sendingSocket;
    	char* buffer1 = malloc(BUFFERSIZE);
    	struct sockaddr_in address;
    	char* adr = "127.0.0.1\0";
    	char temp[255];
    
    	if(sendingSocket = socket(AF_INET, SOCK_STREAM,0) > 0) {
    		printf("Socket zum Senden erfolgreich angelegt\n");
    	}
    
    	address.sin_family = AF_INET;
    	address.sin_port = htons(15000);
    	inet_aton(adr, &address.sin_addr);
    
    	printf("Verbinden?\n");
    	fgets(temp, 254, stdin);
    	if(connect(sendingSocket, (struct sockaddr*)&address, sizeof(address)) == 0) {
    		printf("Erfolgreich verbunden\n");
    	}
    	recv(sendingSocket, buffer1, BUFFERSIZE-1, 0);
    
    	printf("%s\n", buffer1);
    
    }
    
    int main(void) {
    
    	pthread_t listeningID;
    	pthread_t sendingID;
    	char* dummy;
    	int** ret;
    	dummy = "Achja, du schon wieder\0";
    
    	pthread_create(&listeningID, NULL, listeningThread, (void*)dummy);
    	//pthread_create(&sendingID, NULL, sendingThread, (void*)dummy);
    	pthread_join(listeningID, (void**)ret);
    }
    

    Der Listening Thread soll darauf warten, dass ein Verbindungswunsch kommt.
    Der Sending Thread soll abwarten bis man etwas senden möchte und dann senden.
    Aber leider habe ich das bereits oben erwähnte Problem.

    mfg naja



  • Völlig falsches Forum...



  • ach sorry, dann bitte ich darum in das richtige verschoben zu werden.



  • Dieser Thread wurde von Moderator/in Jochen Kalmbach aus dem Forum C++/CLI mit .NET in das Forum Linux/Unix verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.


Log in to reply