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);
}
}
}
}
}
Этот код является лишь примером и нуждается в проверке ошибок, чтобы увидеть, отключился ли клиент, способ обновления списка клиентов и определения готовности клиента к приему данных. Но, надеюсь, это даст вам основную идею, куда идти?