【问题标题】:How to separate between 2 straight sends?如何区分2个直发?
【发布时间】:2017-10-11 20:18:51
【问题描述】:

我正在使用java NIO,我想给播放器发送一条消息,然后立即发送另一条消息。

所以我只是连续发送 2 条消息:

server.send("message 1");
server.send("message 2");

客户端收到消息:

client.read(buffer)

所以缓冲区看起来像这样:

message1+message2

我希望客户将其视为 2 条消息, 问题是我连续两次写入流,客户端一次读取所有流,并获取所有数据(2条消息),就像一条消息一样。

有没有办法检查流是否为空,并且只有在它为空时才写入第二条消息?

【问题讨论】:

  • 分隔您的消息,例如使用换行符,然后逐行阅读。
  • 是的,但是当我使用“socketchannel.read”方法时,它会读取我所有的流吗?我该如何限制它?
  • 在每条消息之前发送一个标头,包含消息中的字节数。
  • 如果您使用 TCP,则由您负责将流结构化为消息。如果您使用 UDP,则由您负责消息重复/错过/排序.任何协议都有工作要做,两者都只是(相对较低级别的)基础设施。

标签: java sockets stream nio


【解决方案1】:

您的问题实际上需要很多答案。作为起点,您应该开始阅读有关网络协议和 Java 套接字编程的文档。协议的发明正是为了解决您面临的问题。此时您需要的最简单的协议是帧协议。

为了让两方(或多方)能够相互理解,您必须定义一种基本的共享“语言”,以便他们能够从连续或伪连续的信息流中提取和解释实际消息。

简而言之,实现远程各方之间通信所需的经典部分通常是:

  • 发送器或写入器(通常是要写入的套接字)
  • 接收器或读取器(通常是要从中读取的套接字 - 通常是缓冲的)
  • 成帧器(相对于您的成帧协议):它对来自流的消息进行成帧。
  • 编解码器(编码器 + 解码器):它们解码成帧的消息或将新消息编码为要发送或写入流的字节。
  • 然后是各种消息的一堆解释器和处理程序
  • 最终,业务逻辑发生在处理程序中,或者由侦听处理程序触发或共享的消息、命令、事件的组件发生。

要严格回答您的问题,如果您使用 TCP 通信,您应该使用帧协议,该协议会在您的消息中添加一个固定长度的消息长度标头。例如。前 2 个字节是消息的长度,然后是消息。如果您使用 UDP,则不太可能需要成帧器,而是需要其他机制。

如果需要,请澄清您的需求,但首先阅读网络协议上可用的广泛文献:从 TCP/UDP 及其差异开始,标头、有效负载、内容、分隔符和帧、缓冲区、完整性、握手、流的优雅关闭的概念, 保活, 编解码器, ...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-02-25
    • 2016-09-17
    • 2023-01-20
    • 1970-01-01
    • 2022-01-18
    • 1970-01-01
    • 2022-10-15
    • 2016-03-21
    相关资源
    最近更新 更多