为什么我的信息被分成多个帧?

时间:2014-01-29 14:26:54

标签: c# .net sockets serialization zeromq

当我向我的服务器发送请求或回复我的客户时,我发送的消息总是分为多个部分。

所以我需要多次调用Receive才能到达最后一个部分/帧。

为什么会发生这种情况..是否有更好的方式来发送和接收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
  }

2 个答案:

答案 0 :(得分:0)

由于您是通过套接字发送的,因此您将受到网络的限制。首先,网络会将您的消息分解为多个包,每个包都由收听者单独接收。听觉机器上的底层套接字会不时地对自己说'有一些传入,但还有更多的东西要来。等一会儿'。过了一会儿,它会说,“好吧,给我得到的东西”并继续等待。

这就是发生的事情。在WCF中,WCF实现通过套接字获取其数据,这完全相同。但是WCF会等到整个消息到达之后再将其提供给您的等待代码。这是使用像WCF这样的框架的优势之一。它可以保护您免受金属的伤害。

答案 1 :(得分:0)

通过TCP发送的任何消息都可以根据其大小分为几个数据包。这就是为什么你永远不会假设一次性收到一条消息,但是在你确定已经收到所有信息之前一直在阅读。