For loop 在循环中写入通道

For loop 在循环中写入通道,for-loop,netty,For Loop,Netty,我必须将大量数据以小数据块的形式发送到连接到服务器的客户端 所以,我有这样的想法: for(;;) { messageEvent.getChannel().write("Hello World"); } 问题是,出于某种原因,客户端正在接收脏数据,比如每次迭代时Netty缓冲区都不清晰,所以我们得到了类似“Hello WorldHello”的东西 如果我在我的代码中做了一点修改,让线程睡眠,那么一切都会正常工作: for(;;) { messageEvent.getChan

我必须将大量数据以小数据块的形式发送到连接到服务器的客户端

所以,我有这样的想法:

for(;;) { 
    messageEvent.getChannel().write("Hello World");
}
问题是,出于某种原因,客户端正在接收脏数据,比如每次迭代时Netty缓冲区都不清晰,所以我们得到了类似“Hello WorldHello”的东西

如果我在我的代码中做了一点修改,让线程睡眠,那么一切都会正常工作:

for(;;) { 
    messageEvent.getChannel().write("Hello World");
    Thread.sleep(1000);
}

在这两种情况下,您都不会发送任何内容来指示一个项目的结束位置和下一个项目的开始位置,或者每个项目的长度


在第二种情况下,睡眠将获得通道超时和刷新,因此客户端将看到一个“中断”,并将其解释为项目的结束。

客户端不应看到此“脏数据”。如果真是这样的话,那就是一个bug。但作为霍恩斯特,我想不出任何可能导致内蒂出现这种情况的事情。因为每个Channel.write(..)事件都将被添加到队列中,然后在可能的情况下写入客户端。因此,在write(..)方法中传递的每个数据都将被写入。数据中没有“concat”

在将数据发送到客户端之前,您是否在管道中有一些自定义编码器来缓冲数据


如果您可以显示给出此行为的完整代码,以便我们查看管道中的处理程序等,这也会有所帮助。

正如MRAB所说,如果服务器在一个通道上发送多条消息而不指示每条消息的结尾,则客户端无法始终正确读取消息。在写消息后增加睡眠时间也不能解决问题的根本原因

要解决此问题,必须以另一方可以识别的方式标记每条消息的结尾,如果客户端和服务器都使用Netty,则可以在json处理程序之前添加LengthFieldPrepender和LengthFieldBasedFrameDecoder

String encodedMsg = new  Gson().toJson(
sendToClient,newTypeToken<ArrayList<CoordinateVO>>() {}.getType());

在这两种情况下,我都不使用任何东西来表示结束。在这两种情况下,客户机根据需要读取尽可能多的输入,或者在创建一个项目时可以读取,然后循环查找下一个项目。如果客户端在读取第一项之前等待了一秒钟以上,那么当它读取输入时,它会看到输入中第一项和第二项的数据,并认为这是一个单一项。我不使用自定义编码器,真正的代码是:for(CoordinateVO坐标:coordinates){sendToClient.add(coordinate);if(sendToClient.size()==2){String resultSerialized=new Gson().toJson(sendToClient,new TypeToken(){}.getType());logger.info(“发送:+resultSerialized”);ChannelBuffer ChannelBuffer=ChannelBuffers.buffer(resultSerialized.getBytes().length);ChannelBuffer.writeBytes(resultSerialized.getBytes());e.getChannel().write(channelBuffer);sendToClient.clear();}}如何添加LengthFieldPrepender和LengthFieldBasedFrameDecode参数?再次感谢!
final static GsonBuilder gsonBuilder = new GsonBuilder().disableHtmlEscaping();

....

String encodedMsg = gsonBuilder.create().toJson(object);