【问题标题】:many io stream from one socket来自一个套接字的多个 io 流
【发布时间】:2015-08-29 07:35:54
【问题描述】:

能否并行连接服务器socket和客户端socket的多个独立I/O流,使每对I/O流可以同时发送不同的数据?

如何在不增加服务器和客户端之间的套接字数量的情况下在 java 中实现这样的连接?

【问题讨论】:

  • 术语是“多路复用”。您只需要用“频道 ID”之类的东西来包装消息,然后在另一端适当地引导它们。
  • @sje397 假设我想从控制台发送一个字符串,同时发送一个比较大的文件。那么当文件准备好发送并且另一个线程正在等待用户的字符串时,多路复用是一种合适的方法吗?

标签: java sockets stream-socket-client


【解决方案1】:

始终有一个输入流和一个输出流,因此您无法添加更多流。

但是,正如 sje397 所评论的,您可以使用相同的流来发送“不同”的数据,您只需要想出一种方法来区分接收端的通道,这样它就可以正确地重构数据。这是一个协议设计问题。

编辑: 在您的示例中,您可以有一个带有标头的数据包结构,该标头告诉数据包的类型(或通道)、数据的长度以及文件数据包的一些附加信息(如果需要)。假设长度字段是一个字节,因此您的最大数据包大小(对于字符串数据包)将为1 + 1 + 255 = 257 bytes

当服务器读取字节时,它将检查第一个字节的数据包类型。确定是String包后,会读取长度,然后读取payload。然后这个过程会不断重复。

对于文件数据,很可能需要额外的标头信息,否则非字符串数据包将只是一堆字节。

这意味着您的协议将成为基于数据包的协议,因此您必须一次写入一个数据包。假设一个数据包的最大大小为 64K,那么您就可以通过以下方式发送数据(假设它是一个网络管道):

Client -> 257(S) -> 64K(D) -> 257(S) -> 64K(D) -> 257(S) -> Server 允许您在单个网络连接中交错两种不同类型的数据。

【讨论】:

  • 假设我想从控制台发送一个字符串,同时发送比较大的文件。由于文件已准备好发送,而另一个线程正在等待用户的字符串,所以我应该设计一个协议来复用所有文件的数据和用户的字符串数据?
  • 谢谢。这真的很有帮助。
【解决方案2】:

假设您希望快速回复控制台输入,我建议使用两个套接字流——一个用于文件数据,另一个用于用户输入。您可以使用ObjectInputStreamObjectOutputStreams 来简化您的协议。只需为您的协议创建一个类,使其可序列化并将其与套接字流一起使用。

【讨论】:

  • 喜欢封装套接字并将其视为单个套接字。但是增加套接字的数量会降低通信通道的链接速度吗?
  • 从一个socket到两个:我很怀疑。
  • 使用ObjectStreams 很少能简化事情,除了一开始(当你注意到“嘿,我可以写一个String 并从另一端读取它!”)。当需求变得更高级时,ObjectStreams 所做的诸如标题和其他技巧之类的事情通常最终会使(初学者)程序员感到困惑。
  • 我也会尝试使用 objectstreams。并会看看我能走多远。再次感谢 KDM 和 Kayaman
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多