【问题标题】:Nonblocking sockets: Are messages queued?非阻塞套接字:消息是否排队?
【发布时间】:2012-04-02 03:27:35
【问题描述】:

据我了解,可以在 PHP 5.x 中创建 nonblocking 网络 socket

但是如果一个脚本使用同一个非阻塞套接字发送多个长消息会发生什么:

socket_write($socket, $string1, $length);
socket_write($socket, $string2, $length);
socket_write($socket, $string3, $length);
socket_write($socket, $string4, $length);

这些消息是否排队(在发送方/接收方?)或者接收方是否有可能因为它们“并行”发送而获得不同消息的一部分?

例如:接收方有可能得到 10 个字节的 $string1,然后是 30 个字节的 $string2,然后是另外 25 个字节的 $string1 ...等等....

【问题讨论】:

    标签: php sockets php-5.3 asyncsocket


    【解决方案1】:

    这取决于套接字使用的协议。有关可能的套接字类型,请参阅socket_create。主要类型有UDP和TCP:

    udp 用户数据报协议是一种无连接、不可靠的协议,具有固定的记录长度。由于这些方面,UDP 需要最少的协议开销。

    tcp 传输控制协议是一种可靠的、基于连接的、面向流的、全双工协议。 TCP 保证所有数据包都将按照它们发送的顺序被接收。如果任何数据包在通信过程中以某种方式丢失,TCP 将自动重新传输数据包,直到目标主机确认该数据包。出于可靠性和性能的原因,TCP 实现本身决定了底层数据报通信层的适当八位字节边界。因此,TCP 应用程序必须考虑到部分记录传输的可能性。

    为了直接回答您的问题,TCP 套接字将保证按顺序交付,而 UDP 套接字则不会。

    【讨论】:

    • 这意味着对于我上面的示例:TCP 套接字将保证接收者在完全接收到 $string1 之前永远不会看到来自 $string2、3 或 4 的数据?
    • 是的,但请记住,所有数据都写入同一个套接字,因此接收器会将数据视为单个信息流。除非您在数据中添加字符串长度、分隔符或其他一些信息,否则接收方将不知道$string1 的结束位置和$string2 的开始位置。
    • @Justin Ethier 这就是我要找的信息! :-) 非常感谢。我还用一个例子更新了我的问题以澄清。
    • @Mike:请记住,这在某种程度上是特定于 PHP 的。如果您启动多线程(PHP 不支持,但 C 或 Java 等其他支持),您必须在您的套接字上实现互斥锁(锁),以防止接收端出现这种奇怪的、意外的行为。
    • @netcoder 这是一个重要的信息,因为我还将创建一个 c# 套接字应用程序。这意味着,我必须锁定一个发送套接字,直到发送完整的数据?如果是这样:为什么不只使用阻塞套接字?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-31
    • 2013-10-15
    • 1970-01-01
    • 2014-11-01
    • 2013-06-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多