Здравствуйте, impure_soul, Вы писали:
_>Здравствуйте, stump, Вы писали:
_>S>>Данные при передаче буфферизуются. Поэтому Socket.Receive (или EndReceive) прчитает столько байт, сколько у него на данный момент есть в буфере. Данные, переданные с клиента одним Socket.Send могут приниматься на другой стороне несколькими Socket.Receive. Об этом надо помнить.
_>Каким образом данные переданные одним Send может принять сразу несколько Receive?
Очень просто. Ты передаешь в Send буфер размером 64К. Сокет начинает передавать эти данные, а другой сокет начинает принимать. Принимающий сокет складывает все принятое в буфер. В это время ты вызываешь Receive и сокет отдает тебе все что есть у него в буфере (допустим 12К). Он не ждет пока придут все 64К потому, что все происходит асинхронно. Он даже не знает что ему должны передать 64К.
_>S>>Если ты передаешь в один сокет не сплошной поток байт, а логически отдельные части, тебе следует предпринять специальные меры, чтобы правильно разделить принимаемый поток на другой стороне.
S>>Например сначала можно посылать размер передаваемых данных (Int32 — 4 байта), а потом сами данные. На другой стороне ты сначала читаешь 4 байта, преобразуешь их в Int32 и видишь размер идущих следом данных. Выделяешь соотвтетствующий буфер и повторяешь Receive пока на прочитаешь их все.
_>Тоесть даже если я пересылаю данные "пакетами" то мне всеравно нужно сначало посылать размер пакета а потом всё остальное?
_>Я не привёл в коде описание пакета и полный код его обработки т.к. много текста, но сам пакет (класс MyMessageType) внутри себя содержит заголовок и часть данных. Потом я его сериализую и отправляю единым потоком. Весь MyMessageType гарантированно помещается в 65К.
Если бы ты для передачи каждого своего сообщения открывал отдельное соединение (сокет) то это не понадобилось бы. Принимал бы все пока не закроется соединение.
_>Я предполагал что сформированный мной пакет и будет для сервера некоторым потоком, а о существовании всех прочих частей (пакетов) он вообще знать не должен. Тоесть он должен принять за один раз не более 65536 байт, bytesRead = client.EndReceive(result) — вернёт мне количество реально полученных байт, далее сервер их перенаправит получателю. Собирать части данных воедино будет уже получатель в соответствии с некоторым алгоритмом (если будет необходимость). А тем временем сервер, перенаправив пакет, должен быть готов принять следующий (возможно даже не имеющий отношения к предыдущему).
_>Может для этого надо сокету на сервере как-то сказать что буфер прошлый нужно очистить?
_>Или я чего-то не понял?
Как я уже сказал выше, сокет не знает где начинаются, а где заканчиваются передаваемые тобой сообщения. Не следует думать что данные переданные тобой в буфере в метод Send являются для сокета како либо логической посылкой. Он просто сливает их дальше вниз по стеку OSI.