当前位置: 首页 > 知识库问答 >
问题:

等待完整的消息到达

束敏学
2023-03-14
MsgLength - 10 positions (in chars, not bytes)
MessageType - 20 positions
Message Number - 9 positions
Timestamp - 19 positions
version - 2 positions
Body - variable (depending on first field)
  private static void Listen()
        {
            while (true)
            {
                //TcpClient client = _listener.AcceptTcpClient();
                allDone.Reset();
                _listener.BeginAcceptTcpClient(new AsyncCallback(AcceptCallback), _listener);
                allDone.WaitOne();
            }
        }


public static void AcceptCallback(IAsyncResult ar)
        {
            // Signal the main thread to continue.
            allDone.Set();

            // Get the socket that handles the client request.
            //TcpListener listener = (TcpListener)ar.AsyncState;
            TcpClient handler = _listener.EndAcceptTcpClient(ar);

            // Create the state object.
            StateObject state = new StateObject();
            state.client = handler;

            handler.GetStream().BeginRead(state.buffer, 0, StateObject.BufferSize, new AsyncCallback(ReadCallback), state);

        }

public static void ReadCallback(IAsyncResult ar)
        {
            String content = String.Empty;
            Encoding enc = Encoding.GetEncoding("ISO-8859-1");

            // Retrieve the state object and the handler socket
            // from the asynchronous state object.
            StateObject state = (StateObject)ar.AsyncState;
            TcpClient handler = state.client;

               int bytesRead = handler.GetStream().EndRead(ar);
        state.TotalHeaderBytesRead += bytesRead;

            if (bytesRead == 60)
            {
                string header = enc.GetString(state.buffer);
                Header h = HeaderParser.Parse(header);
                //todo read the body

                byte[] bodyBuffer = new byte[((HeaderPlaPo)h).Length - 60];
                state.buffer = bodyBuffer;
                handler.GetStream().BeginRead(state.buffer, 0, bodyBuffer.Length, new AsyncCallback(ReadBodyCallback), state);
                Logger.Log(string.Format("received header {0}", header), System.Diagnostics.TraceLevel.Info);
            }
            else
            {
                // Not all data of header received. Get more.
                handler.GetStream().BeginRead(state.buffer, 0, StateObject.BufferSize - state.TotalHeaderBytesRead, new AsyncCallback(ReadHeaderCallback), state);
            }
        }



public static void ReadBodyCallback(IAsyncResult ar)
        {
            Encoding enc = Encoding.GetEncoding("ISO-8859-1");

            // Retrieve the state object and the handler socket
            // from the asynchronous state object.
            StateObject state = (StateObject)ar.AsyncState;
            TcpClient handler = state.client;

            int bytesRead = handler.GetStream().EndRead(ar);
 int bytesRead = handler.GetStream().EndRead(ar);
        state.TotalBodyBytesRead += bytesRead;

        if (state.buffer.Length == state.TotalBodyBytesRead)

这段代码适用于发送数据并关闭连接的客户机,但是当使用一个连接的客户机多次发送时,数据没有被读取->我应该在读取完整正文后关闭连接吗?

共有1个答案

邬浩涆
2023-03-14

你没有提到你使用什么语言,我给出了Java的例子,如果你需要用其他语言让我知道。无论如何,您需要在一次关闭中读取60(10+20+9+19+2)字节。将前10个字节(字符)转换为整数,然后将该字节数读入byte[]数组。

例如:

try
{
    byte[] buffer = new byte[60];
    mySocket.getInputStream().read(buffer, 0, 60);
    String header = buffer.toString();
    int length = Integer.parseInt(header.substring(0, 9));
    byte[] body = new byte[length];
    mySocket.getInputStream().read(body, 0, length);
}
catch (Exception e)
{
   e.printStackTrace();
}

编辑:更改为C#

 byte[] buffer = new byte[60];
 mySocket.Receive(buffer, 60, SocketFlags.None);
 // You should ckeck this, UTF7 or UTF8 or UNICODE, etc
 string header = Encoding.UTF7.GetString(buffer, 0, 60);
 int length = Convert.ToInt32(header.Substring(0, 10));
 byte[] body = new byte[length];
 int offset=0;
 // Keep reading the socket until all bytes has been received
 while (length > 0) 
 {
     int ret=mySocket.Receive(body, offset, length, SocketFlags.None);
     if (ret > 0) 
     {
        offset += ret;
        length -= ret;
     }
     else 
        if (ret == 0) 
        {
            // peer has close the socket
        }
        else
        {
           // there is an error in the socket.
        }

  }
 类似资料:
  • 我正在使用hiredis C库连接到redis服务器。我不知道在订阅新消息后如何等待新消息。 我的代码如下所示: 现在如何告诉雇佣者在频道上等待消息?

  • 问题内容: 我正在使用hiredis C库连接到redis服务器。我无法弄清楚订阅新消息后如何等待新消息。 我的代码如下所示: 现在如何告诉hiredis在频道上等待消息? 问题答案: 您无需告诉hiredis您需要在通道上等待:事件循环将仅在先前已注册的Redis连接上等待。 这是一个完整的示例: 您可以通过使用以下命令发布内容来对其进行测试: event_base_dispatch函数是实际启

  • Hi akka古鲁们:)你能在这一次指导我吗? 我要做的是-演员A向演员B要消息,然后等一个回来。但是,不知何故,演员B给A的不是一条信息,而是其中的4条信息。A正确完成,但rest消息中有3条被算作死信。为什么?这样对吗?我是说,演员A有一个合适的处理人,那为什么信都死了?:-( [INFO][11/22/2013 22:00:38.975][ForkJoinPool-2-worker-7][a

  • 当在客户端和服务器之间使用WebSocket全双工数据连接时,我是否保证,当从服务器发送两条消息时,我将在客户端接收到这两条完全相同的消息,而TCP没有这样做? 换句话说,如果服务器依次发送,然后发送,那么客户机是否总是接收包含和的两条消息,或者客户机是否可能接收,然后接收之类的消息?

  • 是否有一种方法可以尝试等待一段时间,然后返回不同的结果,而不取消超时后的未来? 我有一个服务(我们称之为),它跑出去做自己的事情。它返回一个结果: 我愿意[阻止并]等待它一小段时间(比方说2秒)。如果它没有完成,我希望返回一个不同的结果,但我希望服务继续做它自己的事情。然后查询服务是否完成(例如,通过websockets或其他方式)将是客户端的工作。 即。我们有以下几个案例: 花费%1 s并完成其

  • 问题内容: 我有一个调用一些不检查线程中断的代码。调用之后,该方法将立即抛出(如预期的那样)。但是,由于后台任务的代码从不检查其线程是否被中断,因此它很乐意继续执行。 是否有等待后台任务 实际 完成的标准方法?我希望显示“正在取消…”消息或某种类似的内容,直到任务终止为止。(我确信如果有必要,我总是可以在worker类中使用一个标志来完成此操作,只需寻找其他解决方案即可。) 问题答案: 我玩了一点