2014-01-29 4 views
1

Когда я отправляю запрос на свой сервер или ответ на мой клиент, сообщение, которое я отправляю, всегда делится на несколько частей.Почему мое сообщение делится на несколько кадров?

Так что мне нужно позвонить Получать несколько раз, чтобы добраться до последней части/кадра.

Почему это происходит .. есть ли лучший способ отправки и получения строки, закодированной в xml?

Это код моего клиента:

private void SendRequestAsyncTaskStart<T>(object contextObj, T request) 
    { 
    ZmqContext context = (ZmqContext)contextObj; 
    ZmqSocket requestSocket = CreateServerSocket(context); 

    SerializeAndSendRequest(request, requestSocket); 
    } 

    private ZmqSocket CreateServerSocket(ZmqContext context) 
    { 
    var client = context.CreateSocket(SocketType.REQ); 
    client.Connect(_requestReplyEndpoint); 
    client.Linger = TimeSpan.Zero; 
    client.ReceiveReady += PollInReplyHandler; 

    return client; 
} 

public static string Serialize(this object obj) 
    { 
    string result; 

    using (var memoryStream = new MemoryStream()) 
    { 
     using (var reader = new StreamReader(memoryStream)) 
     { 
      var serializer = new DataContractSerializer(obj.GetType()); 
      serializer.WriteObject(memoryStream, obj); 
      memoryStream.Position = 0; 
      result = reader.ReadToEnd(); 
     } 
    } 

    return result; 
    } 

Это код моего сервера:

private void ListenForRequestsThreadStart(object contextObj) 
    { 
    ZmqContext context = (ZmqContext)contextObj; 

    using (
     ZmqSocket frontend = context.CreateSocket(SocketType.REP), 
     backend = context.CreateSocket(SocketType.DEALER)) 
    { 
     string bindAddress = string.Format("tcp://*:{0}", _listenForRequetsPort); 
     frontend.Bind(bindAddress); 
     backend.Bind("inproc://backend"); 

     frontend.ReceiveReady += HandleRequestReceived; 

     // polling 
    } 
    } 

    private void HandleRequestReceived(object sender, SocketEventArgs e) 
    { 
    string message; 

    bool hasNext; 
    do 
    { 
     message = socket.Receive(Encoding.ASCII); 
     hasNext = socket.ReceiveMore; 
    } while (hasNext); 

    // after calling Receive 3 times i get my actual message 
    } 

ответ

0

Поскольку вы отправляете через сокет вы находитесь в благости сеть. Во-первых, сеть сломает ваше сообщение в нескольких пакетах, каждый из которых будет получен отдельно вашим слушателем. Время от времени базовый сокет на слушающей машине скажет себе: «Получил некоторые входящие, но еще впереди. Подожди немного'. Через некоторое время он скажет: «Ну, дайте то, что у меня есть» и продолжайте ждать ».

Это то, что происходит. В WCF реализация WCF получает свои данные через сокеты, которые делают то же самое. Но WCF ждет, пока сообщение не поступит, прежде чем передать его вашему ожидающему коду. Это одно из преимуществ использования Framework, такого как WCF. Он защищает вас от металла.

+0

Хорошо, я понимаю, что tcp разбивает сообщения на несколько сегментов. Я думал, zmq будет абстрагировать это для меня и ждать, пока сообщение не появится, потому что это действительно низкий уровень протокола. Нужно ли мне делать это самостоятельно? – leozilla

+1

Я бы проверил документы ZMQ, но ZmqSocket, имеющий метод ReceiveMore(), подразумевает, что вполне возможно, что сообщение поступит поэтапно. Может быть какая-то настройка, которая говорит: «Подождите, пока вы не получите все сообщение, прежде чем поднимать событие приема» –

0

Любое сообщение, отправленное через TCP, может быть разделено на несколько пакетов в зависимости от его размера. Вот почему вы должны никогда не предположить, чтобы получить сообщение за один раз, но прочитайте, пока не убедитесь, что получили все.

+0

Хорошо, я понимаю, что tcp разбивает сообщения на несколько сегментов. Я думал, zmq будет абстрагировать это для меня и ждать, пока сообщение не появится, потому что это действительно низкий уровень протокола. Нужно ли мне делать это самостоятельно? – leozilla

Смежные вопросы