SCTP заказал доставку сообщений
Можно ли заставить SCTP отправлять все данные в полном порядке?
Давайте сделаем этот эксперимент:
1) Возьми этот SCTP-Discard-сервер и этот 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 %d\n", (int)buffer[0], (int)(test));
if ((int)test != (int)buffer[0]) break;
Несколько секунд спустя:
66 66
67 67
68 68
69 69
51 70
Вуаля!
Я скомпилировал это с $ gcc discard_server.c -Wall -lusrsctp
используя gcc7.3.0 на моей машине с Ubuntu 18.04. И да, я уже пытался отключить все виды nagel-алгоритмов с помощью SCTP_NODELAY
,
Что я упустил? Заранее спасибо за любой намек.
2 ответа
Я узнал что usrsctp_sendv(..)
может потерпеть неудачу, если буфер сокета заполнен, например. Это то, что произошло.
Я старался while(usrsctp_sendv(..) < 0)
и теперь клиент и сервер считают в правильном направлении.
Вероятно, вы упускаете тот факт, что SCTP не гарантирует последовательную доставку в рамках ассоциации. Последовательная доставка гарантируется только в потоке.
Как RFC 4960 глава 1.5.2 говорит:
Внутренне SCTP назначает порядковый номер потока каждому сообщению, переданному ему пользователем SCTP. На принимающей стороне SCTP гарантирует, что сообщения доставляются пользователю SCTP последовательно в заданном потоке. Однако, хотя один поток может быть заблокирован в ожидании следующего последовательного пользовательского сообщения, доставка из других потоков может продолжаться.
Я предполагаю, что у вас настроено более одного Steam, а используемая реализация распределяет нагрузку между потоками. Это должно быть легко подтверждено следом проволочной акулы.
Если у вас есть порядок сообщений, вы должны указать идентификатор потока при отправке данных и проверить идентификатор потока при получении.