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 不保证关联内的顺序传递。仅在流内保证顺序传送。
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)
,现在客户端和服务器计数正确。
是否可以强制 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 不保证关联内的顺序传递。仅在流内保证顺序传送。
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)
,现在客户端和服务器计数正确。