LINUX.ORG.RU

socket.send склеивает сообщения

 


0

2

Всем доброго времени суток!

Простите за, вероятно, нубский вопрос, но столкнулся с тем, что в python3, если быстро отправить два коротких сообщения, они могу быть восприняты как одно. Вот такой код:

msg = "a2"
s.send(msg.encode('ascii'))
msg = "b1"
s.send(msg.encode('ascii'))
приводит к тому, что иногда на выходе сообщение «a2b1», вместо двух «a2» и «b1». Возможно ли этого избежать или это нормально и надо продумывать обработку склеенных сообщений?

★★★★★

Это нормально. Используй разделители сообщений или указатель длины сообщений, чтобы разделять их при приёме. Будь готов к тому, что они могут не только склеиваться, но и приходить кусками.

unC0Rr ★★★★★
()
Последнее исправление: unC0Rr (всего исправлений: 1)

Пока решил проблему, жёстко ограничив размер принимаемого сообщения, но не хотелось бы так себя ограничивать.

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

Спасибо! Про приходить кусками я как-то не подумал. Буду думать и обрабатывать сообщения.

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

Спасибо. Как раз подумывал про UDP. Возможно, в моём случае это будет удобнее.

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

Может что-то более высокоуровневое надо использовать, чтобы не городить сборку сообщений вручную?

Или сделать маркер начала и конца сообщения, и ждать их на принимающей стороне, вычитывая из сокета всё принятое.

Radjah ★★★★★
()

Они вообще могут по одной букве к тебе прийти. Разделяй сообщения переводом строки и читай как readline.

panter_dsd ★★★★
()

А протокол то какой снизу? SOCK_DGRAM - не нормально, SOCK_STREAM - нормально.

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

и типа после этого посыпятся сообщения не дробясь? чето сомневаюсь в этом

например в QTCPSocket нет возможности слать сообщения детерминировано, только если протокол поверх

I-Love-Microsoft ★★★★★
()
Последнее исправление: I-Love-Microsoft (всего исправлений: 2)

TCP (если ты его используешь) - это поточно-ориентированный протокол, в нём нет границы между сообщениями

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

Переделываю на UDP, посмотрим, что получится.

Сообщения могут не дойти. Или дойдут в другой последовательности. Или будут продублированы

Harald ★★★★★
()

Эт нормально... Почитай что-нибудь про сокеты, там все просто и доходчиво,тср лучше удп если ты не стримишь видео или звук... Или ещё что,где данные быстро устаревают

jo_b1ack ★★★★★
()

какая задача стоит? Для rpc есть всякие zeromq и прочее что решает многие проблемы «обычных» сокетов.

Ну и это, по tcp/udp/ip неплохо бы подтянуть матчасть. Особенно про надёжность и очерёдность доставки. Хинт: tcp это стриминговый протокол, у потока нет понятия «сообщения». тебе нужно будет нарезать поток на куски самому или же взять какое-либо готовое решение для этого.

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

Ну, не всё так плохо! UDP отлично подошло.

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

какая задача стоит?

Пульт управления роботом на соревнованиях.
Пока UDP показывает себя лучше.
Связь достаточно хорошая, потерь не наблюдаю.
Матчасть буду подтягивать, хотя бы из интереса.

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

UDP быстрее, чем TCP,
но как отметили выше, это протокол «без гарантированной доставки»: датаграммы (пакеты) могут теряться или приходить в другой последовательности.

А TCP может склеиваться и дробиться, это тоже верно отметили.

Если юзаешь TCP, то воспринимай весь приём как единый поток, и передавай длину в каждом куске (я так делаю).

А если юзаешь UDP, то заведи индекс и по нему отслеживай порядок и потери кусков. При обнаружении потери, делай дозапрос и досылку. А при смене порядка (если это важно) - сортируй.

Novator ★★★★★
()
Последнее исправление: Novator (всего исправлений: 1)
Ответ на: комментарий от Novator

Спасибо.
Как я уже говорил, у меня пульт управления роботом. Поэтому скорость UDP для меня важна. Порядок сообщений практически не важен, нет разницы, запустится сначала, скажем, правый мотор, а потом левый, если между ними разница в 10мс.
Потери, как ни странно, наблюдаю, хотя связь идёт по WiFi и роутер совсем рядом. Но редко. Так что создание индекса возьму на заметку, спасибо, но пока гораздо больше проблем с отзывчивостью приводов.

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

Спасибо, но размер программы довольно критичен — память робота ограничена. Пока что все проблемы с сетью решил, спасибо!

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