using select to read from socket and stdin
Solution 1
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'.
Solution 2
You need to specify the highest file descriptor to select:
if (select(s + 1,&read_fds,NULL,NULL,NULL) == -1){
select() needs to know the number of file descriptors that it is supposed to watch.
Related videos on Youtube
michauwilliam
Updated on May 31, 2022Comments
-
michauwilliam almost 2 years
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.
-
Mario The Spoon about 13 yearsalso do not use FD_ZERO( 0, use FD_SET( fileno( stdin ), ...
-
-
michauwilliam about 13 yearsit is suppose to watch only 2 descriptors - stdin and s
-
Richard Pennington about 13 yearsNo, the number isn't the number of file descriptors, it's the one greater than the highest file descriptor. and "s + 1" is certainly bigger than 2.