2

我制作了一个简单的 tcp 服务器/客户端应用程序,客户端向服务器写入一些内容,然后将其回显给客户端。但是,当我尝试读取服务器在客户端回显的内容时遇到了一些问题。

string s;
while((n = read(socketFD[0],readBuf, BUFFER_SIZE)) > 0){
  cout<<"\nBytes read: "<<n<<endl;
  s.append(readBuf, n);
}
cout<<"\nTest after read\n";

我将 16 KB 的文本写入服务器。当我在客户端阅读时,我一次阅读 4 KB。

这段代码的输出是:

Bytes read: 4096

Bytes read: 4096

Bytes read: 4096

Bytes read: 4046

read 调用似乎在完成从套接字读取之后阻塞并且永远不会离开循环。我怎样才能解决这个问题?

编辑:这是处理连接客户端的服务器中的代码。

if((childpid = fork()) == 0){
  close(listenFD);
  while ((n = read(connectFD, buf, BUFFSIZE)) > 0){
    cout<<"\nBytes read: "<<n<<endl;
    write(connectFD, buf, n);
  }
  cout<<"\nTest after read\n";
  exit(0);
}

这个输出是:

Bytes read: 4096

Bytes read: 4096

Bytes read: 4096

Bytes read: 4046

Test after read

与客户端中的代码相比,这里有什么不同?为什么读取调用不像在客户端那样阻塞?

4

3 回答 3

0

read 调用似乎在完成从套接字读取之后阻塞并且永远不会离开循环。我怎样才能解决这个问题?

read简短的回答,收到所有数据后不要打电话。

编写代码来检测您何时收到了当时想要接收的所有数据,如果是,则退出循环。您必须实际实现某种协议。

s+=readBuf;

这不可能。它如何知道要添加多少字节的数据s

于 2012-11-24T16:11:01.213 回答
0

如果您不想将读取循环放在另一个线程中,您将需要轮询选择,这样您就可以查看队列中是否存在某些内容,而无需实际读取它。

于 2012-11-24T16:08:38.383 回答
0

这是对 Python 中套接字的非常好的介绍的摘录。它是 Python,是的,但它公开了 C-Socket API,所以那里写的内容在您的上下文中也是正确的。你可以在这里阅读:http: //docs.python.org/dev/howto/sockets.html

关于“使用套接字”的部分准确地告诉您您正在观察的问题是什么。它讨论了recv函数,但它转换为read文件描述符上的函数。

但是,如果您打算重用您的套接字进行进一步的传输,您需要意识到套接字上没有 EOT。我再说一遍:如果一个套接字 send 或 recv 在处理 0 个字节后返回,则连接已断开。如果连接没有断开,您可能会永远等待 recv,因为套接字不会告诉您没有更多要阅读的内容(现在)。现在,如果您稍微考虑一下,您就会意识到套接字的一个基本事实:消息必须是固定长度的(yuck),或者是定界的(耸肩),或者表明它们有多长(更好),或者以关闭连接结束。选择完全是你的,(但有些方法比其他方法更正确)。

于 2012-11-24T16:46:03.977 回答