SCTP заказал доставку сообщений - PullRequest
0 голосов
/ 06 января 2019

Можно ли заставить 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 %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 ]

0 голосов
/ 08 января 2019

Я обнаружил, что usrsctp_sendv(..) может потерпеть неудачу, например, если буфер сокета заполнен. Вот что случилось.

Я попытался while(usrsctp_sendv(..) < 0), и теперь клиент и сервер считают правильно.

0 голосов
/ 07 января 2019

Что вам, вероятно, не хватает, так это тот факт, что SCTP не гарантирует последовательную доставку в рамках ассоциации. Последовательная доставка гарантируется только в потоке.

Как RFC 4960 глава 1.5.2 говорит:

Внутренне SCTP назначает порядковый номер потока каждому сообщение, переданное ему пользователем SCTP. На принимающей стороне SCTP гарантирует, что сообщения доставляются пользователю SCTP в последовательности в данном потоке. Однако пока один поток может быть заблокирован ожидание следующего в последовательности пользовательского сообщения, доставка от другого потоки могут продолжаться.

Полагаю, у вас настроено более одного steam, а используемая реализация распределяет нагрузку между потоками. Это должно быть легко подтверждено следом Wireshark.

Если вы переносите порядок сообщений, вы должны указать идентификатор потока при отправке данных и проверить идентификатор потока при его получении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...