选择插座和标准

Select on socket and stdin

本文关键字:标准 插座 选择      更新时间:2023-10-16

我正在试验选择,并有一个简单的应用程序,无论用户在命令行中输入什么,都可以写入服务器。然后,服务器将其回显。我正在使用选择功能来侦听连接的套接字和标准。

客户端代码:

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] = '';
    cout<<"nSocket read!n";
    cout<<readArr;
  }
}

现在,如果我在命令行中键入"Hello!"并按回车键,我会得到以下输出:

Hello! //User input
Socket write!//Client output
Socket read!//Client output

如果我再次按回车键,则会打印"Hello!"。为什么我需要按两次回车键?

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

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

你的cin>>input不会读一整行,只读一个单词。它不会读取换行符,如果您键入两个单词,它不会读取第二个单词。您可能应该改用getline(cin,input),它读取整行并放入input(没有换行,它被丢弃)。