是否可以强制SCTP发送所有数据完全有序?
让我们做这个实验:
1) 拿这个 SCTP 丢弃服务器和这个 SCTP 客户端。
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 %dn", (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 第 1.5.2 章所说:
在内部,SCTP 为每个流序列号分配一个流序列号由 SCTP 用户传递给它的消息。 在接收方,SCTP确保按顺序将邮件传递给 SCTP 用户在给定流中。 但是,虽然一个流可能会被阻止等待下一条按顺序的用户消息,从其他消息传递流可能会继续。
我猜您配置了多个蒸汽,并且您使用的实现在流之间分配负载。这应该很容易通过wireshark跟踪来确认。
如果您携带消息顺序,则应在发送数据时指定流 ID,并在到达时检查流 ID。
我发现,如果套接字缓冲区已满,usrsctp_sendv(..)
可能会失败。事情是这样的。
我尝试了while(usrsctp_sendv(..) < 0)
,现在客户端和服务器计数是正确的。