2017-02-21 1 views
0

Bisher hat alles perfekt funktioniert. Nur das Problem, das ich habe, ist, dass ich nicht eine Art der Zuweisung oder ich würde sagen, Namen zu den Clients, die mit dem Server verbunden sind, so dass andere Clients, die wissen, ist eine Nachricht schreiben schrieb eine Nachricht schreiben :Unix-Socket Mehrere Client-Gruppen-Chat mit Client-Namen in c

while (1) { 
    FD_ZERO(&read_set); 
    //FD_ZERO(&write_set); 

    FD_SET(fd, &read_set); 
    //FD_SET(fd, &write_set); 

    for (i = 0; i < num_clients; i++) { //at first this part will not excute 
     FD_SET(clients[i], &read_set); 
    } 

    select(fd + num_clients + 1, &read_set, NULL, NULL, NULL); 


    if (FD_ISSET(fd, &read_set)) { 
     if ((clients[num_clients++] = accept(fd, NULL, NULL)) == -1) { 
      perror("accept error"); 
      continue; 
     } 
     printf("we got a connection!\n"); 
    } 


    for (i = 0; i < num_clients; i++) { 

     if (FD_ISSET(clients[i], &read_set)) { 
      msg = read(clients[i], buf, sizeof(buf)); 
      if (msg > 0) { 
       int savedclnt = clients[i]; 
       printf("client %d says: %s\n", i, buf); 

       for (int p = 0; p<num_clients; p++) 
       { 
        if (clients[p] != savedclnt) { 
         //write("from %d",clients[p]); 
         //char msg2 = strcat(clients[i],msg); 
         write(clients[p], buf, msg); 
        } 

       } 
      } 
     } 
    } 
} 
+0

Welche Probleme haben Sie mit dem angezeigten Code? Was ist deine Frage? Bitte nehmen Sie sich etwas Zeit (lesen Sie, wie Sie gute Fragen stellen können) (http://stackoverflow.com/help/how-to-ask). –

+0

Das Problem, das ich hatte, ist, dass ich nicht daran denken kann, dass der Server jede Nachricht schreibt, die ein Client über den Socket an alle anderen Clients sendet. Ich habe andere ähnliche Beiträge hier gelesen und es war hilflos. –

+1

Zunächst schlage ich vor, dass Sie entweder versuchen [Gummi Ente Debugging] (https://en.wikipedia.org/wiki/Rubber_duck_debugging) oder zumindest durchlaufen Sie den Code Zeile für Zeile in einem Debugger. Das liegt daran, dass Sie einige Probleme mit der Handhabung von Threads haben. Behalten Sie für Ihr Problem eine Sammlung aller verbundenen Clients bei und lesen Sie die Eingabeschleife über diese Sammlung, um sie an alle anderen Clients zu schreiben. Ein Array oder eine Liste von Dateideskriptoren ist ein guter Anfang. –

Antwort

0

Für das, was Sie tun, brauchen Sie nicht wirklich Threads. Aus persönlicher Erfahrung würde ein Single-Thread-Server die Arbeit gut machen. Statt den Wrap-Hauptkörper um einen Anruf zu accept() zu haben, sollten Sie select() verwenden, um zu sehen, welche Datei-Deskriptoren haben Eingang, etwas entlang der Linien von ...

fd_set readfds; 
struct timeval timeout; 
unsigned int num_clients; 
unsigned int clients[100]; 
while(1) 
    { 
    FD_ZERO(&readfds); 
    FD_SET(sock, &readfds); 
    for(i=0; i<num_clients; i++) 
    { 
    FD_SET(clients[i],&readfds); 
    } 
    timeout.tv_sec=1; 
    timeout.tv_usec=0; 
    select(max_fds, &readfds, NULL, NULL, &timeout); 
    if(FD_ISSET(sock,&readfds)) 
    { 
    clients[num_clients++] = accept(sock,(struct sockaddr *)&server,&size); 
    } 
    for(i=0;i<num_clients;i++) 
    { 
    if(FD_ISSET(clients[i],&readfds)) 
     { 
     int err=read(clients[i],buf,1000); 
     if(err>0) 
     { 
     for(p=0;p<num_clients;p++) 
      { 
      write(clients[i],buf,err); 
      } 
     } 
     } 
    } 
    } 

Dieser Code ist nur ein Beispiel und muss die Fehlerprüfung an Sehen Sie nach, ob ein Client die Verbindung getrennt hat, eine Möglichkeit, die Liste der Clients zu aktualisieren und festzustellen, ob ein Client bereit ist, Daten zu empfangen. Aber hoffentlich gibt es dir die Grundidee, wohin du gehen sollst?

+0

Ich bin nicht wirklich vertraut mit Select() -Methode, aber ich aktualisiere meinen Code mit einem einzigen Thread, wie Sie vorgeschlagen, aber immer noch nicht geben, was ich will –

+0

Ich aktualisierte den Code vielleicht Sie einen Blick. –

+0

Die Funktion 'select()' wartet höchstens eine Sekunde oder bis eine der Dateibeschreibungen im Bit-Set readfds eine Eingabe hat. –