使用select来读取socket和stdin

我正在写一个基于ncurses的聊天程序。 起初,我只编写网络内容(没有ncurses),一切正常,但添加图形后,我无法使客户端应用程序正常工作。

主要问题是同时从stdin和socket读取。 在ncurses-less版本中,我使用了pthread,它就像魅力一样。 唉,似乎pthread和ncurses没有很好地结合在一起,所以我不得不寻找另一种解决方案。 我认为select()会这样做,但它仍然只从stdin读取并完全忽略套接字。

这是整个代码: 代码

有趣的是:

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

有可能我不完全理解select()是如何工作的,或者我不应该在socket中使用connect()…我迷失在这里。 我将不胜感激任何帮助! 谢谢。

你的问题出在select()
第一个参数不是您在read_fds中传递的文件描述符的数量 ,但它是最高的套接字ID + 1。

从手册页:

在每组中检查第一个nfds描述符; 即,检查描述符集中从0到nfds-1的描述符。 (示例:如果您设置了两个文件描述符“4”和“17”,则nfds不应为“2”,而应为“17 + 1”或“18”。)

所以在你的代码中,而不是’2’,尝试传递’s + 1’。

您需要指定要选择的最高文件描述符:

 if (select(s + 1,&read_fds,NULL,NULL,NULL) == -1){ 

select()需要知道它应该观察的文件描述符的数量。