使用选择读取套接字和标准输入 [英] using select to read from socket and stdin

查看:95
本文介绍了使用选择读取套接字和标准输入的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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.

主要问题是同时从stdin和socket读取.在无ncurses的版本中,我使用了pthread,它的工作方式就像魅力. las,看来pthread和ncurses结合得不是很好,所以我不得不寻找另一种解决方案. 我以为select()可以,但是它仍然只从stdin读取,而完全忽略套接字.

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.

这是完整的代码:代码

有趣的部分是:

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()的工作方式,或者我不应该使用connect()套接字.我将不胜感激任何帮助!谢谢.

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.

推荐答案

您的问题出在select()中.
第一个参数是不是您在 read_fds 中传递的文件描述符的数量,但这是最高的套接字ID + 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.

在手册页中:

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

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".)

因此,在您的代码中,请尝试传递"s + 1"而不是"2".

So in your code, instead of '2', try passing 's+1'.

这篇关于使用选择读取套接字和标准输入的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆