使用套接字同时发送多种类型

Sending many types at the same time with a socket

我想将对应于几种不同类型(为简单起见,一个浮点数和一个整数)的单个数据流从一个套接字发送到另一个套接字(从 ServerSocket accept() 创建)。但是,我不确定实现此目标的最佳方法是什么。如果我想使用 readInt() 或 readFloat() 似乎我需要单独发送它们,我想这不太理想(但如果我错了请指正)。

代码将从执行以下操作开始(假设 float 将存储在 b 的前 4 个字节中,而 int 将存储在 b 的最后 4 个字节中)

ServerSocket socket = new ServerSocket(port);
in=new DataInputStream(socket.accept().getInputStream());

byte[] b = new byte[8];
in.read(b);

到目前为止一切顺利,但我现在只想将前四个字节转换为 float,将最后四个字节转换为 int。我可以做类似

的事情
float myFloat = ByteBuffer.wrap(b).getFloat();

获取浮点数,但如何获取整数?在 C++ 中,我只是将引用传递给 b 中的第五个元素,但据我所知,这在 java 中是不可能的。当然我可以使用一些库从 b 的最后四个元素创建一个新数组,但这似乎有点矫枉过正不是吗?或者这是唯一的方法吗?

非常感谢关于通过套接字同时发送多种不同类型的任何其他建议。

使用 Serializable 包装器 class 来存储不同类型的值,并使用 ObjectInputStream & ObjectOutputStream 来读写 class 实例似乎是实现这一目标的最佳方式。 Here and here 是很好的参考资料。

I want to send a single stream of data [...] from a Socket to a ServerSocket

很抱歉我吹毛求疵,但你不能那样做。 ServerSocket 是一种接受连接请求并建立基于套接字的通信通道的本地端的机制。该本地端一旦建立,就由 Socket 表示,因此您似乎想要做的是将数据从 Socket 发送到 Socket .

但您的问题似乎主要是关于通过通信通道发送混合数据。在这种情况下,要考虑的第一个问题是接收方如何知道在任何给定点尝试读取的类型。这归结为在通信双方之间有一个应用层通信协议。这不一定是正式的或宏伟的;在您的示例中,似乎有一个共同的理解,即数据将作为 32 位二进制 float 后跟 32 位二进制 int 发送。那是一个协议。

If I want to use readInt() or readFloat() it seems that I need to send them separately, and I guess that would not be ideal

我不明白你的意思。是的,您确实需要知道哪些数据是 ints,哪些是 floats,但这并不能将 DataInputStream.readInt()DataInputStream.readFloat() 的使用与任何其他机制区分开来。

对于您传输的每个数据,您有两个基本选择:

  1. 指望接收方依赖一些事先约定或假设来确定如何解释该数据(可能扩展到识别其在线表示的边界),或

  2. 与数据一起传输元数据,接收器将使用该元数据按预期解释数据。

当然,(2)可以看作是(1)的特例。

如果一条消息总是由一个浮点数和一个整数组成,那么我认为发件人使用

没有任何问题
myDataOutputStream.writeFloat(f);
myDataOutputStream.writeInt(i);

接收方通过

处理
myDataInputStream.readFloat(f);
myDataInputStream.readInt(i);

的确,对于那种简单的情况,我认为这是一个很好的选择。

然而,更一般地说,在选择或设计通信协议时还有许多其他考虑因素。对该主题的一般性讨论对于这个场所来说太宽泛了。