LINUX.ORG.RU

tcp socket send отправка сообщения целиком


0

0

Приветствую!

Люди, подскажите кто знает плиз, есть ли возможность у tcp-сокетов (linux, не винда) в случае tcp-соединения отсылать данные «цельно»?

В случае датаграмного udp у меня таких проблем и вовсе не было - что recvrom что sendto всегда принимали/отправляли цельно.

А можно ли сделать такое в случае tcp-соединения? Как я понял в случае recv можно задать флаг MSG_WAITALL, а вот как быть в случае отправки? Есть ли возможность задания каких-либо флагов/опций сокетов, чтобы как в udp можно было «цельно» отправлять пакеты, размер мне заранее известен.

Заранее спасибо!


По-умолчанию сокет в блокирующем режиме и программа будет заблокирована, пока в буфер сокета не скопируются все данные.

Kristi
()

«цельно» это как?

send() ты можешь сделать с любым размером буффера, но вот размер фрейма Ethernet, например, ограничен где-то 1518 байтами, поэтому твоё добро все равно раздробят.

На другом конце, например, ты можешь сделать recv() с заданным размером (он же тебе известен) и не париться по поводу фрагментации.

А какого размера данные предполагается слать на один send()?

yoghurt ★★★★★
()
Ответ на: комментарий от yoghurt

> «цельно» это как?

Это чтобы одним send'ом отправить, а не кучей send'ов.

Просто не хотелось бы while делать, в котором оценивать сколько байт уже отправлено и доотправлять все остальное, хотелось бы одним send'ом.

На другом конце, например, ты можешь сделать recv() с заданным
размером (он же тебе известен) и не париться по поводу фрагментации.

Да, известен, 1464 байта.

А какого размера данные предполагается слать на один send()?

Такие же, 1464. Просто в мане по send и recv не нашел на тему того, будет ли проходить разбиение, если я четко хочу отправить или принять какое-то количество байт, вот и плаваю (.

anonymous
()

MSG_WAITALL нужен в тех случаях, когда ты ожидаешь получить от сервера, например, 128 байт, а он отправил тебе 64, и спустя скажем 10 секунд - ещё 64.

yoghurt ★★★★★
()
Ответ на: комментарий от yoghurt

>> 1464 байта

Ну, это же не 10 мегабайт :)
Отправляй одним send-ом, принимай одним recv-ом и не парься

Просто беспокоит, что делать в том случае, если он отправит (или примет) не 1464, а половину, треть, etc. Можно ли избежать такого на уровне настроек?

anonymous
()
Ответ на: комментарий от yoghurt

> MSG_WAITALL нужен в тех случаях, когда ты ожидаешь получить от

сервера, например, 128 байт, а он отправил тебе 64, и
спустя скажем 10 секунд - ещё 64.

Ну так я примерно так и хотел сделать - ставить этот флаг и принимать ровно 1464 байта.

deadka
() автор топика

Легко и просто, формируешь пакет своими ручками, тоесть выделяешь память для тела, заполняешь заголовки, какие угодно опции...флаги и тд проставляешь, считаешь контрольные суммы..и отправляешь в сеть.. Всё просто.

Deleted
()
Ответ на: комментарий от anonymous

>Просто беспокоит, что делать в том случае, если он отправит (или примет) не 1464

Если ты в send указываешь размер отправляемого буфера в 1464, то на другой конец придет ровно столько

yoghurt ★★★★★
()
Ответ на: комментарий от yoghurt

>> Просто беспокоит, что делать в том случае, если он отправит (или примет) не 1464

Если ты в send указываешь размер отправляемого буфера в 1464,
то на другой конец придет ровно столько

char szMessage[1464]=«Здесь могла быть ваша реклама.................»; // точками szMessage добивается до 1464

int s;

// инициализация сокета

int nSend=send(s,szMessage,sizeof(szMessage),0);

Ок ), скажите, я правильно понял, что в переменной nSend окажется -1 (и там уже разбираемся с errno) либо 1464?

Может ли в nSend оказаться другое значение, например 512?

anonymous
()
Ответ на: комментарий от anonymous

Гарантий нет, но в линуксе вроде как оно дождется отправки.

OxiD ★★★★
()
Ответ на: комментарий от anonymous

>то на другой конец придет ровно столько

блин! забыл дописать ", сколько вернуло send".

Может ли в nSend оказаться другое значение, например 512?

Вполне. http://stackoverflow.com/questions/2618736/why-is-it-assumed-that-send-may-re...

yoghurt ★★★★★
()
Ответ на: комментарий от yoghurt

>>Может ли в nSend оказаться другое значение, например 512?

Вполне.
http://stackoverflow.com/questions/2618736/why-is-it-assumed-that-...

Да, вот от этого я и отталкивался изначально, что придется писать нечто вроде вот такой отправки ). Спасибо всем!!

deadka
() автор топика
Ответ на: комментарий от Boy_from_Jungle

> что-то как-то тяжело у тебя все получается

можно гораздо легче

А как именно гораздо легче? Если можно с примером кода :-[

deadka
() автор топика

man tcp... provides a reliable, stream-oriented, full-duplex connection

Ты видишь что-то про «пакеты»? TCP может добраться до пропихивания твоих данных по 1му байту за раз, и это нужно учитывать.

DonkeyHot ★★★★★
()

для write должна быть всегда логика подобная read

vasily_pupkin ★★★★★
()

Наверное тебе нужен SCTP. А tcp сообщения бьет и читает как угодно и MSG_WAITALL тут особо не поможет.

sergej ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.