在socket和stdin上选择

时间:2012-11-28 23:37:39

标签: c++ sockets

我正在尝试使用select并拥有一个简单的应用程序,无论用户在命令行输入什么,都可以写入服务器。然后服务器回复它。我正在使用select函数来监听连接的套接字和标准输入。

客户代码:

const int BUFFER_SIZE = 1024;
char *readArr = new char[BUFFER_SIZE];
fd_set rset;
ssize_t n;
string input;
FD_ZERO(&rset);
while(true){
  FD_SET(socketFD[0], &rset);
  FD_SET(0, &rset);

  maxfpd1 = max(socketFD[0], 0) + 1;
  select(maxfpd1, &rset, NULL, NULL, NULL);
  if(FD_ISSET(0, &rset)){
    cin>>input;
    write(socketFD[0], input.c_str(), input.size());
    cout<<"\nSocket write!\n";
  }
  if(FD_ISSET(socketFD[0], &rset)){
    n = read(socketFD[0], readArr, BUFFER_SIZE-1);
    readArr[n] = '\0';
    cout<<"\nSocket read!\n";
    cout<<readArr;
  }
}

现在,如果我输入“你好!”在命令行中按Enter键,我得到这个输出:

Hello! //User input

Socket write!//Client output

Socket read!//Client output

如果我再次点击进入,“你好!”打印出来。为什么我需要输入两次?

我可以从服务器输出看到,在第一次输入后,消息被正确发送到服务器,然后再返回。

2 个答案:

答案 0 :(得分:1)

cin>>input未从该行的末尾读取换行符,cout<<readArr未写入换行符。如果使用cout<<readArr<<endl,它将在字符串后面写一个换行符并刷新输出缓冲区。如果您不想在字符串后面添加换行符,则可以使用flush而不是endl来仅刷新输出缓冲区。如果您不希望缓冲输出,也可以将cout更改为无缓冲。

答案 1 :(得分:0)

您的cin>>input不会读一整行,只读一个字。它不会读取换行符,如果您键入两个单词,则不会读取第二个单词。您应该使用getline(cin,input)来代替整个行,然后输入input(没有换行,这会被丢弃)。