Сокет не отправляет все содержимое в Linux (Ubuntu) - PullRequest
3 голосов
/ 13 августа 2011

Я столкнулся с проблемой при отправке больших сегментов данных через сокет TCP, потратив около 3 дней на то, чтобы разобрать проблему, и при неудаче решил, что лучше обратиться сюда за помощью / советом.

Мой проект Я написал базовый HTTP-сервер, который (немного не имеет значения) может запускать сценарии lua для вывода страниц. Все это прекрасно работает под Windows (32 бита).

Проблема

При отправке средних / больших файлов (примерно от 8000 байт и выше возникают проблемы) через TCP-сокет в Ubuntu Linux (64-битная версия) они выглядят обрезанными с различной длиной (результат, отображаемый в браузере: значение между 8000 и 10200 байт. Когда я проверяю возвращаемое значение функции отправки, это точно 9926 байт каждый раз, когда отправка заканчивается. Нет ошибок.

Меньшие файлы отправляются абсолютно нормально, и под Windows нет проблем. Продолжая эту информацию, я подумал, что это может быть проблема размера буфера, поэтому я сделал

cat /proc/sys/net/ipv4/tcp_mem

который вывел 188416 192512 196608

эти цифры намного выше 9926, поэтому я полагаю, что это не проблема.

Я использую CSimpleSockets в качестве библиотеки сокетов, у меня раньше не было проблем. В случае, если проблема находится внутри этой библиотеки, код, который я нашел, для определения функции отправки, используемой в unix:

#define SEND(a,b,c,d)          send(a, (const int8 *)b, c, d)

send(socket, buffer, bytestosend, 0);

буфер передается от const char * до const unsigned char* до const int8 * перед передачей в ОС для отправки.

ОК, я думаю, это охватывает все, что я проверял Если вам нужна дополнительная информация или я пропустил что-то явно очевидное, я сделаю все возможное, чтобы предоставить. Спасибо за вашу помощь!

Ответы [ 2 ]

4 голосов
/ 13 августа 2011

Ваша проблема в том, что send не гарантирует отправку объема данных, переданных ему.

Он имеет внутренние буферы, которые могут заполнять, параметры сокетов, которые влияют на буферы, и т. Д. Вы должны отметить, сколько байтовбыли отправлены, подождите несколько миллисекунд (для отправки, чтобы переместить данные по проводам и очистить буфер), затем отправьте оставшиеся данные.Не существует автоматического способа сделать это, и вам нужно написать немного логики, которая увеличивает ваш буфер на количество фактически отправленных байтов.

2 голосов
/ 13 августа 2011

Вы используете блокирующие или неблокирующие розетки?Если вы используете неблокирующие сокеты, вы должны (а с блокирующими сокетами вы должны ) проверить на короткий send (тот, где возвращаемое значение меньше, чемколичество байтов, которое вы намеревались отправить).

...