Re[2]: Быстрая пересылка через Socket
От: impure_soul Россия  
Дата: 10.10.07 13:46
Оценка:
Здравствуйте, stump, Вы писали:


S>Данные при передаче буфферизуются. Поэтому Socket.Receive (или EndReceive) прчитает столько байт, сколько у него на данный момент есть в буфере. Данные, переданные с клиента одним Socket.Send могут приниматься на другой стороне несколькими Socket.Receive. Об этом надо помнить.


Каким образом данные переданные одним Send может принять сразу несколько Receive?

S>Если ты передаешь в один сокет не сплошной поток байт, а логически отдельные части, тебе следует предпринять специальные меры, чтобы правильно разделить принимаемый поток на другой стороне.
S>Например сначала можно посылать размер передаваемых данных (Int32 — 4 байта), а потом сами данные. На другой стороне ты сначала читаешь 4 байта, преобразуешь их в Int32 и видишь размер идущих следом данных. Выделяешь соотвтетствующий буфер и повторяешь Receive пока на прочитаешь их все.


Тоесть даже если я пересылаю данные "пакетами" то мне всеравно нужно сначало посылать размер пакета а потом всё остальное?
Я не привёл в коде описание пакета и полный код его обработки т.к. много текста, но сам пакет (класс MyMessageType) внутри себя содержит заголовок и часть данных. Потом я его сериализую и отправляю единым потоком. Весь MyMessageType гарантированно помещается в 65К.

    public class MyMessageType
    {
        MyMessageTypeHeader header;

        MyMessageTypeData data;

        public MyMessageTypeHeader Header
        {
            get { return header; }
            set { header = value; }
        }

        public MyMessageTypeData Data
        {
            get { return data; }
            set { data = value; }
        }
       ...
    }

    public class MyMessageTypeHeader
    {
        byte[] UID;

        User userFrom;

        User usersTo;
        
        Int64 part;
        Int64 partsCount;

        MessageType messageType;
        
        DateTime timeStamp = DateTime.Now;

        Dictionary<string, string> parameters;
       ...
    }

    public class MyMessageTypeData
    {
        Dictionary<string, string> parameters;

        public Dictionary<string, string> Parameters
        {
            get { return parameters; }
            set { parameters = value; }
        }

        byte[] dataContainer;

        public byte[] DataContainer
        {
            get { return dataContainer; }
            set { dataContainer = value; }
        }
    }


Я предполагал что сформированный мной пакет и будет для сервера некоторым потоком, а о существовании всех прочих частей (пакетов) он вообще знать не должен. Тоесть он должен принять за один раз не более 65536 байт, bytesRead = client.EndReceive(result) — вернёт мне количество реально полученных байт, далее сервер их перенаправит получателю. Собирать части данных воедино будет уже получатель в соответствии с некоторым алгоритмом (если будет необходимость). А тем временем сервер, перенаправив пакет, должен быть готов принять следующий (возможно даже не имеющий отношения к предыдущему).
Может для этого надо сокету на сервере как-то сказать что буфер прошлый нужно очистить?
Или я чего-то не понял?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.