SCTP 有序消息传递

SCTP ordered message delivery

是否可以强制 SCTP 发送完全有序的所有数据?

让我们做这个实验:

1) 拿这个 SCTP-discard-server and this SCTP-client.

2)让客户端数到100多次,每次分别发送一个字节给服务器

for(long i=0; i< 1000000000; i++){
    char temp = (char)(i%100) + 1;
    usrsctp_sendv(
        sock, (void *)&temp, 1,
        NULL, 0, NULL, 0, SCTP_SENDV_NOINFO, 0
    );
}

3) 让服务器沿相同的方式计数,并与接收到的数进行比较。

printf("%d %d\n", (int)buffer[0], (int)(test));
if ((int)test != (int)buffer[0]) break;

几秒钟后:

66 66
67 67
68 68
69 69
51 70

瞧!

我在 Ubuntu 18.04 机器上使用 gcc7.3.0$ gcc discard_server.c -Wall -lusrsctp 编译了这个。是的,我已经尝试通过 SCTP_NODELAY 禁用各种 nagel 算法。

我错过了什么?预先感谢您的任何提示。

您可能忽略的事实是 SCTP 不保证关联内的顺序传递。仅在流内保证顺序传送。

正如RFC 4960 chapter 1.5.2所说:

Internally, SCTP assigns a Stream Sequence Number to each message passed to it by the SCTP user. On the receiving side, SCTP ensures that messages are delivered to the SCTP user in sequence within a given stream. However, while one stream may be blocked waiting for the next in-sequence user message, delivery from other streams may proceed.

我猜你配置了不止一个流,你使用的实现在流之间分配负载。这应该很容易用 wireshark trace 确认。

如果您进行消息排序,您应该在发送数据时指定流 ID,并在数据到达时检查流 ID。

我发现,usrsctp_sendv(..) 可能会失败,例如,如果套接字缓冲区已满。事情是这样的。

我试过 while(usrsctp_sendv(..) < 0),现在客户端和服务器计数正确。