使用非阻塞Perl套接字时,为什么不能获取所有数据?

时间:2009-10-13 04:55:57

标签: perl sockets

我在AIX 5.3中使用Perl套接字,Perl版本5.8.2

我有一个用Perl套接字编写的服务器。有一个名为“Blocking”的选项,可以设置为0或1.当我使用Blocking => 0并运行服务器和客户端发送数据(5000字节)时,我只能在一次调用中收到2902个字节。当我使用Blocking => 1时,我能够在一次通话中收到所有字节。

这是套接字如何工作还是错误?

2 个答案:

答案 0 :(得分:6)

这是套接字的基本部分 - 或者更确切地说,TCP,它是面向流的。 (UDP是面向数据包的。)

你永远不应该假设你会收到你要求的数据,也没有更多的数据可用。在连接打开时,基本上可以随时获得更多数据。 (read / recv /任何调用可能会返回一个特定值来表示“另一端关闭连接。”

这意味着您必须设计协议来处理此问题 - 如果您有效地尝试将离散消息从A传递到B,则执行此操作的两种常用方法是:

  • 使用长度为每封邮件添加前缀。读者首先读取长度,然后继续读取数据,直到读取所需数据为止。
  • 有某种消息终止符/分隔符。这比较棘手,因为根据您正在做的事情,您可能需要注意在阅读第一条消息时读取下一条消息的开头的可能性。它还意味着在“读取”代码中“理解”数据本身,而不是仅仅任意读取字节。但是,它确实意味着发件人在开始发送之前不需要知道消息的持续时间。

(另一种方法是只为整个连接提供一条消息 - 即直到连接关闭才能读取。)

答案 1 :(得分:2)

阻塞意味​​着套接字在从接收函数返回之前等待直到有数据存在。完全有可能在最后还有一个小小的等待,以便在返回之前尝试填充缓冲区,或者它可能只是一个时间问题。非阻塞实现完全有可能一次返回一个数据包,无论是否存在多个数据包。简而言之,不,它不是一个错误,但具体的“为什么”它是旧的警察“它是特定于实现”。