我怎样才能收到消息?



我正在维护一个c#系统,其部分工作是从随机客户端接收tcp消息(使用socket.recv())。我们确实有一个消息协议,因此外部开发人员可以填充格式良好的消息。

消息格式如下:

{ public data(fixed length):private data(variable length) }

要接收消息,我们需要在此消息中使用私有数据长度字段,但是需要有人发送可能填充了错误的长度数字的消息。我怎样才能满足这个需求?

下面是我的代码:

public static int ReceiveMessage(int totalByteNumber, Socket socket, byte[] recvBuffer)
{
  try
  {
    int offset = 0;
    do
    {
      try
      {
        int num = socket.Receive(recvBuffer, offset, totalByteNumber - offset, SocketFlags.None);
        if (num == 0)
        {
          throw new ApplicationException();
        }
        offset += num;
      }
      catch (SocketException ex)
      {
        if (ex.SocketErrorCode == SocketError.IOPending || ex.SocketErrorCode == SocketError.NoBufferSpaceAvailable)
          Thread.Sleep(30);
        else if (ex.SocketErrorCode == SocketError.WouldBlock)
        {
          socket.Blocking = true;
          Thread.Sleep(30);
        }
        else
        {
          LogManager.WriteError("Origin IP:" + (object) ((IPEndPoint) socket.RemoteEndPoint).Address);
          throw ex;
        }
      }
    }
    while (offset < totalByteNumber);
    return offset;
  }
  finally
  {
    SocketUtility.LogMessage("Recv", recvBuffer, socket);
  }
}

不能容纳格式不正确的消息,至少不可靠。TCP不维护消息边界,因此您无法知道发送给您的消息有多长。

在实践中,如果您通常有短请求,并且请求者在一个send系统调用中发送整个请求,则每个接收方很可能只返回一条请求消息,但这并不可靠。例如,如果请求者连续向您发送两个请求,那么它们可能会在您的流程被调度之前合并,以便在单个接收调用中将两个请求返回给您。

你的选择:

  • 消息中的长度字段,告诉您期望的长度(大多数二进制协议都以这种方式工作)
  • 消息中的一些标志模式(空字节,或空文本行,或其他);基于文本的协议(如HTTP)通常以这种方式工作)
  • 文件结束(即呼叫者可以发送请求,然后调用socket.Shutdown(Send);,你会得到EOF,知道这是所有的期望;显然这是一次性交易)

相关内容

  • 没有找到相关文章

最新更新