Help!!!Пересылка большого объёма через SOCK_STREAM
От: GenadyT  
Дата: 22.11.01 18:25
Оценка:
Здаравствуйте!!!
Первый раз на этом форуме; очень даже симпатичный форум:).
Есть проблема!!!
В своей серверной апликации я использую SOCK_STREAM сокет.
При передаче не большого кол-ва данных, всё нормально.
Но если идёт передача большого кол-ва данных(30 000 — 40 000 байт), то TCP/IP разбивает данные на куски(причём разной длинны).
Например у меня клиент посылает 30000 байт, а сервер получает три куска(8000, 17000 и 5000 байт).Т.е. у серверного сокета функция OnReceive вызывается три раза.
Соответственно при приёме я должен считывать по отдельности каждый кусок а потом собирать всё вместе. Вот именно этого я и хочу избежать. Возможно ли сделать так, чтоб мне не приходилось собирать эти куски вручную.
Говорят, есть чтото связанное с функцией IOCtl() и её параметром FIONREAD? Может ктото в курсе?
Спасибо!!! :???:
Best regards!
Genady.
Re: Help!!!Пересылка большого объёма через SOCK_STREAM
От: retalik www.airbandits.com/
Дата: 23.11.01 06:09
Оценка: 4 (1)
Здравствуйте GenadyT, Вы писали:

GT>Здаравствуйте!!!

GT>Первый раз на этом форуме; очень даже симпатичный форум.
GT>Есть проблема!!!
GT>В своей серверной апликации я использую SOCK_STREAM сокет.
GT>При передаче не большого кол-ва данных, всё нормально.
GT>Но если идёт передача большого кол-ва данных(30 000 — 40 000 байт), то TCP/IP разбивает данные на куски(причём разной длинны).
GT>Например у меня клиент посылает 30000 байт, а сервер получает три куска(8000, 17000 и 5000 байт).Т.е. у серверного сокета функция OnReceive вызывается три раза.
GT>Соответственно при приёме я должен считывать по отдельности каждый кусок а потом собирать всё вместе. Вот именно этого я и хочу избежать. Возможно ли сделать так, чтоб мне не приходилось собирать эти куски вручную.
GT>Говорят, есть чтото связанное с функцией IOCtl() и её параметром FIONREAD? Может ктото в курсе?
GT>Спасибо!!!

Сложный вопрос...
Когда я занимался сокетами, у всех была противоположная проблема: так называемый алгоритм Нагля сливал несколько маленьких пакетов в один (или несколько) средних, в результате чего нельзя было предсказать, за сколько приемов придут данные. Похоже, уши растут именно оттуда. (Посмотри в MSDN Nagle algorithm, Q214397, Q147714).

Насколько я понимаю, FIONREAD тут не поможет — он только определит размер блока, уже стоящего в очереди.

С другой стороны, в программировании сокетов еще со времен Berkeley Sockets не рекомендовали полагаться на размер stream-пакета — а, например, передавать признак конца данных или служебную информацию (общую длину).
Успехов,
Виталий.
Re: Help!!!Пересылка большого объёма через SOCK_STREAM
От: Shilon Молдова  
Дата: 01.12.01 18:53
Оценка:
Здравствуйте GenadyT, Вы писали:

GT>Здаравствуйте!!!

GT>Первый раз на этом форуме; очень даже симпатичный форум.
GT>Есть проблема!!!


Все равно в итоге надо будет сопровождать пакет с инфой насчет длины,
Re: Help!!!Пересылка большого объёма через SOCK_STREAM
От: Eugene  
Дата: 01.12.01 20:24
Оценка: 4 (1)
Здравствуйте GenadyT, Вы писали:
GT>Но если идёт передача большого кол-ва данных(30 000 — 40 000 байт), то TCP/IP разбивает данные на куски(причём разной длинны).

Retalic прав, пакеты могут как разбиваться на более мелкие, так и "сливаться", например, при интенсивной передаче и задержке с чтением, и при передаче структурированных данных надо учитывать и то, и другое. Обычная практика — обрамлять кадры служебной информацией, включая сигнатуру и длину в заголовок. Тогда удобно читать заголовок, определять длину и далее "дочитывать" (возможно, за несколько приемов)собственно данные, каждый раз запрашивая для чтения остаток длины, чтобы не "напороться" на данные следующего пакета и не "захватить" лишнего.
Don't trouble trouble until trouble troubles you
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.