繁体   English   中英

如何接收通过TCP套接字发送的相同消息?

[英]How to receive the same messages sent via TCP socket?

我在Java中有一个TCP套接字客户端-服务器程序。

从客户端,我每秒钟发送几次二进制消息(来自byte []的二进制数据)。

从服务器,我想以相同的顺序和大小读取这些消息。

问题是服务器显然并不总是读取相同大小的消息。 似乎将它们“分组”。 例如:

客户端发送:12个字节-12个字节-12个字节-12个字节-15个字节-15个字节

服务器接收:12个字节-48个字节-15个字节-15个字节

我该如何预防?

现在,我的代码是:

客户:

(initialization)
mySocket = new Socket(direccion, puerto);
mySocket.setTcpNoDelay(true);
BufferedOutputStream os = new BufferedOutputStream( mySocket.getOutputStream() );

(sending)
os.write( bytes );
os.flush();

服务器

(initialization)
serverSocket = new ServerSocket(12321);
Socket con = serverSocket.accept();
reader = new BufferedReader(new InputStreamReader(con.getInputStream()));

(receiving)
char[] msg = new char[1024];
String mensaje;
int nbytes;
nbytes = reader.read(msg);

我无法手动分离分组的消息,因为它们是二进制消息,并且该模块无法“理解”它们。

因此,问题是:如何确保读者单独获得消息?

谢谢

您正在使用数据来传输消息。 从概念上讲,流只是字节序列-没有消息 您需要自己将流分割为消息/数据包。 您甚至可以在当前代码中通过一次调用获得消息的一部分,而通过下一次调用获得消息的一部分。 现在,您的代码从根本上来说是有缺陷的。

引入一种机制,该机制可以清楚地检测消息的开始/结束位置。 一种简单的方法是将每个数据包的长度编码为每个数据包的第一个字节。 然后,接收器可以先读取长度,然后再知道该包中有多少个后续字节。

另一种方法是具有一个消息分隔符符号,该符号指示当前数据包的结束。 由于您正在发送二进制数据,因此这将要求数据包不包含所有可能的字节值,或者您需要以不使用所有可能的字节值的方式对数据包进行编码。

具有长度的方法更易于实现,而结束符号方法对于您可以轻松引入新符号的方案(例如,如果整个数据包都经过霍夫曼编码)很有用。

TCP连接传输流的本质是TCP。

您的选择是

  1. 手动分隔消息,例如,在每条消息之前添加一个长度字段。 这需要更改协议。

  2. 使用不同于TCP的协议。 要么是UDP(但是却失去了可靠性),要么是STCP(我不确定Java是否能够做到这一点)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM