I've been learning about sockets and also learned about the select() system call which makes one able to accept and handle multiple connections. On the process of making a simple chat (in C) I noticed that every time one user of the chat writes something, the app prints everything the user writes plus what the user wrote. Like this:
[user1] hello
[user2] hello
[user2] good morning
[user1] hello
[user1] have a nice day
[user2] hello (this was already printed)
[user2] good morning (this too was already printed)
[user2] thank you
[user1] hello (already printed)
[user1] have a nice day (already printed)
[user1] you're welcome
Is this a consequence of using the select function?
Here's the source code of the server:
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/time.h>
#include <time.h>
struct peer {
char * nick;
int socketfd;
};
int main(int argc, char *argv[]){
struct peer peers[100];
int sockfd,newsockfd,port;
socklen_t clilen;
char buffer[255];
struct sockaddr_in serv_addr,cli_addr;
int n;
sockfd=socket(AF_INET,SOCK_STREAM,0);
bzero((char *) &serv_addr, sizeof(serv_addr));
port=atoi(argv[1]);
serv_addr.sin_family=AF_INET;
serv_addr.sin_addr.s_addr=INADDR_ANY;
serv_addr.sin_port=htons(port);
if(bind(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0){
}
listen(sockfd,5);
fd_set rfds,afds;
int size,npeer=0,nfds=getdtablesize();
FD_ZERO(&afds);
FD_SET(sockfd,&afds);int status;
for(;;){
memcpy(&rfds,&afds,sizeof(rfds));
status=select(nfds,&rfds,(fd_set *)0,(fd_set *)0,(struct timeval *) 0);
if(status < 0 )
perror("select: ");
if(FD_ISSET(sockfd,&rfds)) {
clilen=sizeof(cli_addr);
newsockfd=accept(sockfd,(struct sockaddr *) &cli_addr,&clilen);
FD_SET(newsockfd,&afds);
}
for(int fd=0;fd<nfds;fd++){
if(fd != sockfd && FD_ISSET(fd,&rfds)){
bzero(buffer,255);
n=read(fd,buffer,255);
for(int i=0;i<nfds;i++) {
if(i != sockfd && FD_ISSET(i,&afds)){
write(i,buffer,255);
}
}
printf("%s\n",buffer);
}
}
}