Unix socket Многопользовательский групповой чат с именем клиента в 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);
                    }

                }
            }
        }
    }
}

1 ответ

Решение

Для того, что вы делаете, вам не нужны темы. Исходя из личного опыта, однопоточный сервер прекрасно справился бы с этой задачей. Вместо того, чтобы основное тело обернуть вокруг вызова accept() ты должен использовать select() чтобы увидеть, какие файловые дескрипторы имеют ввод, что-то вроде...

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

Этот код является лишь примером и нуждается в проверке ошибок, чтобы увидеть, отключился ли клиент, способ обновления списка клиентов и определения готовности клиента к приему данных. Но, надеюсь, это даст вам основную идею, куда идти?

Другие вопросы по тегам