Threaded-Server.verschiedene-Ports
-
Tut mir wirklich sehr leid!
Hier ist der Code nochmals in schöner Form:#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <string.h> #include <pthread.h> #include <time.h> #include <string.h> #include <sys/stat.h> #define BUFFER_SIZE 1024 char *port; char command [2000]; int array[65535]; char in [10000]; char input_[10000]; int check = 0; int connect_ (int port) { int s, c; struct sockaddr_in srv, cli; socklen_t cli_size; s = socket(AF_INET, SOCK_STREAM, 0); srv.sin_addr.s_addr = INADDR_ANY; srv.sin_port = htons( (unsigned short int) port); srv.sin_family = AF_INET; if (bind(s,(struct sockaddr*) &srv, sizeof(srv)) == -1) { perror("bind() failed"); return 3; } if (listen(s, 3) == -1) { perror("listen() failed"); return 4; } for(;;) { cli_size = sizeof(cli); c = accept(s, (struct sockaddr *) &cli, &cli_size); printf("Client connected on Port: \n"); printf("%d\n", port); // Testen ob ein Befehl vorliegt! for (;;) { if (array[port] == 1) { array[port] = 0; send (c, command, strlen(command), 0); // Warte auf Antwort check = recv(c, input_, sizeof(input_) -1, 0); if (check == -1) { printf("Error receiving\r\n"); } printf("%s", input_); int i = 0; for (i = 0; i < 10000; i++) { command[i] = '\0'; in[i] = '\0'; input_[i] = '\0'; } } } // EOF //close(c); } } void input () { int p_port; for (;;) { scanf("%s", in); if (!strncmp(in, "use", 3)) { printf("Use command accepted, awaiting ID:\r\n"); // Jetzt lesen wir die Zahl ein! scanf("%s", in); printf("ID accepted, awaiting command:\r\n"); p_port = atoi(in); // Hier werden die Befehle erwartet for (;;) { scanf("%s", in); strcat (command, in); array[p_port] = 1; } } else { printf("Read the man page for more information\nHelp: use Port\r\n"); } //printf("%s", in); //printf("\r\n"); } } int main (int argc, char* argv[]) { if (argc < 3) { printf("Usage: ./server Number_of_listen_sockets startportnumber\n\n"); return 1; } int k = atoi(argv[1]); int port = atoi(argv[2]); int i = 0; printf("%d\n", k); for (i=0; i<k; i++) { printf("Creating Socket on Port "); printf("%d", port + i); printf("\n"); pthread_t tid; pthread_create(&tid, NULL, connect_, port+i); //connect_(port + i); //printf("%d", i); } // Creating main thread for IO pthread_t pid; pthread_create (&pid, NULL, input, NULL); for (;;) { sleep(120); } }
-
hat keiner eine idee an was es liegen könnte?
-
Was mir so beim drüberschauen auffällt: die einzelnen Threads scheinen in die Arrays zu schreiben und zu lesen ohne Rücksicht aufeinander.
Das macht mit Sicherheit Probleme.Tipp: benutz zum Setzen des Speichers doch memset statt der for-Schleife.
-
Ja das memset werde ich einbauen, ob es zum Sachverhalt was ändert ist ne andere Frage.
Die einzelnen Threads schreiben ja zwar in das selbe array aber an verschiedenen Stellen. Außerdem habe ich es nur mit einem Client getestet => es wird auch nur ein Thread auf das Array schreiben!
-
Aber du hast doch (mindestens) 2 Thread Input + Connect - auch bei nur einem Client.
Die beiden Funktionen benutzen doch die Arrays und laufen in getrennten Threads.
So kann es passieren, dass A auf ein Array schreibt und B währenddessen liest.-> B liest Müll
-
ja schon.
aber das erklärt ja nicht warum der server einmal was empfängt, dann nur teile und dann nichts.das array wird nur für die interne kommunikations des servers verwendet, dass er weiß wann der user einen befehl eingetippt hat. was an den server gesendet wird, wird ja per recv() ausgewertet.
oder verstehe ich was falsch?
-
also scheinbar ist API lesen nicht mehr modern. denn wenn man sich die API von pthread anschaut sieht man, dass soetwas hier nicht funktionieren kann:
pthread_create(&tid, NULL, connect_, port+i);
auch dein compiler gibt warnungen.
server.c: In Funktion »main«: server.c:141: Warnung: Übergabe des Arguments 3 von »pthread_create« von inkompatiblem Zeigertyp server.c:141: Warnung: Übergabe des Arguments 4 von »pthread_create« erzeugt Zeiger von Ganzzahl ohne Typkonvertierung server.c:147: Warnung: Übergabe des Arguments 3 von »pthread_create« von inkompatiblem Zeigertyp
blan
-
wie muss es dann heißen?
lg
-
theaded schrieb:
wie muss es dann heißen?
pthread_create erwartet eine Funktion von folgendem Typ:
void * (*func) (void*)
Also hier in deinem Fall:
static void * connect_(void* vport) { int port = (int) vport; ... if (bind(...) == -1) { ... return (void*) 3; } ... } ... pthread_create(&tid, NULL, connect_, (void*)(port+i)); ...
Wobei ich die Casts nicht bevorzugen würde, da dabei ein int in einem
void* versteckt wird.Dann doch lieber so:
static void *connect_(void* threadargs) { int port = *(int*)threadargs; ... if (bind(...) == -1) { *(int*)threadargs = 3; return threadargs; } } ... int *threadargs = malloc(k*sizeof(*threadargs)); for (i=0; i<k; ++i) { threadargs[i] = port+i; pthread_create(&tid, NULL, connect_, threadargs+i); } ...
Ich hoffe, ich habe mich verständlich genug ausgedrückt und du erkennst
den Unterschied.Gruß mcr
-
Ja danke, war sehr verständlich!
Habe das verstanden.Nun habe ich meinen Code entsprechend abgeändert, jedoch funktioniert es leider trotzdem nicht
-
threader schrieb:
Ja danke, war sehr verständlich!
Habe das verstanden.Nun habe ich meinen Code entsprechend abgeändert, jedoch funktioniert es leider trotzdem nicht
gib uns bitte mal auch den Code von deinem Client, damit wir esauch mal ausprobieren können. Danke.
Gruß mcr