I'm writing a ncurses based chat program. At first, I wrote just networking stuff (without ncurses) and everything worked fine, but after adding graphics I can't get the client app to work properly.
The main problem is reading from stdin and socket at the same time. In ncurses-less version I've used pthread and it worked like charm. Alas, it seems that pthread and ncurses don't go together very well, so I had to find another solution. I thought that select() would do, but it still only reads from stdin and completely ignores the socket.
Here is the whole code: code
The interesting part is:
char message[1024];
fd_set master;
fd_set read_fds;
FD_ZERO(&master);
FD_ZERO(&read_fds);
FD_SET(0,&master);
FD_SET(s,&master); // s is a socket descriptor
while(true){
read_fds = master;
if (select(2,&read_fds,NULL,NULL,NULL) == -1){
perror("select:");
exit(1);
}
// if there are any data ready to read from the socket
if (FD_ISSET(s, &read_fds)){
n = read(s,buf,max);
buf[n]=0;
if(n<0)
{
printf("Blad odczytu z gniazdka");
exit(1);
}
mvwprintw(output_window,1,1,"%s\n",buf);
}
// if there is something in stdin
if (FD_ISSET(0, &read_fds)){
getstr(message);
move(CURS_Y++,CURS_X);
if (CURS_Y == LINES-2){
CURS_Y = 1;
}
n = write(s,message,strlen(message));
if (n < 0){
perror("writeThread:");
exit(1);
}
}
}
It's possible that I don't fully understand how select() works, or maybe I shouldn't have connect()ed the socket.. I'm lost here. I would appreciate any help! Thanks.
Your problem is in the select()
.
The first parameter is not the number of file descriptors you are passing in read_fds, but it's the highest socket ID + 1.
From the man page:
The first nfds descriptors are checked in each set; i.e., the descriptors from 0 through nfds-1 in the descriptor sets are examined. (Example: If you have set two file descriptors "4" and "17", nfds should not be "2", but rather "17 + 1" or "18".)
So in your code, instead of '2', try passing 's+1'.