DataOutputStream 未刷新

发布于 2024-08-13 04:22:25 字数 511 浏览 2 评论 0原文

我有一个 Java 客户端,它将 UTF-8 字符串发送到 C# TCP 服务器,我使用 DataOutputStream 发送字符串。代码如下所示:

public void sendUTF8String(String ar) {
    if (socket.isConnected()) {
        try {
            dataOutputStream.write(ar.getBytes(Charset.forName("UTF-8")));
            dataOutputStream.flush();
        } catch (IOException e) {
            handleException(e);
        }
    }
}

问题是刷新似乎无法正常工作。如果我发送两个彼此靠近的字符串,服务器只会收到一条包含这两个字符串的消息。如果我在调用之间执行 Thread.sleep(1000) ,整个事情就会起作用,这显然不是一个解决方案。 我缺少什么?

I have a Java Client which sends UTF-8 strings to a C# TCP-Server, I'm using a DataOutputStream to send the strings. The code looks like this:

public void sendUTF8String(String ar) {
    if (socket.isConnected()) {
        try {
            dataOutputStream.write(ar.getBytes(Charset.forName("UTF-8")));
            dataOutputStream.flush();
        } catch (IOException e) {
            handleException(e);
        }
    }
}

The problem is that flush doesn't seem to work right. If I send two Strings close to each other, the server receives only one message with both strings. The whole thing works if I do a Thread.sleep(1000) between calls, this is obviously not a solution.
What am I missing?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

那伤。 2024-08-20 04:22:25

flush() 不保证数据包被发送出去。您的 TCP/IP 堆栈可以自由地捆绑您的数据,以实现最大效率。更糟糕的是,您和目的地之间可能存在许多其他 TCP/IP 堆栈,并且它们可以随意执行相同的操作。

我认为你不应该依赖数据包捆绑。在数据中插入逻辑终止符/分隔符,这样您就安全了。

flush() doesn't guarantee that a data packet gets shipped off. Your TCP/IP stack is free to bundle your data for maximum efficiency. Worse, there are probably a bunch of other TCP/IP stacks between you and your destination, and they are free to do the same.

I think you shouldn't rely on packet bundling. Insert a logical terminator/divider in your data and you will be on the safe side.

梓梦 2024-08-20 04:22:25

您不必担心数据如何分解为数据包。

您应该在消息中包含字符串的长度,然后在接收端首先读取该长度。因此,例如发送给你会做

byte[] arbytes = ar.getBytes(Charset.forName("UTF-8"));
output.writeInt(arbytes.length)
output.write(arbytes)

,然后在你的阅读器中你做

byte[] arbytes = new byte[input.readInt()];
for(int i = 0; i < len; i++){
     arbytes[i] = input.read();
}
//convert bytes back to string.

你不能只调用 input.read(arbytes) 因为读取函数不一定读取数组的整个长度。您可以执行一个循环,一次读取一个块,但其代码有点复杂。

无论如何,你明白了。


另外,如果您真的想要控制数据包中的内容,您可以使用数据报套接字,但如果您这样做,则无法保证数据包的传送。

You shouldn't worry about how the data is broken up into packets.

You should include the length of the string in your messages, and then on the receiving end you would read the length first. So for example to send you would do

byte[] arbytes = ar.getBytes(Charset.forName("UTF-8"));
output.writeInt(arbytes.length)
output.write(arbytes)

and then in your reader you do

byte[] arbytes = new byte[input.readInt()];
for(int i = 0; i < len; i++){
     arbytes[i] = input.read();
}
//convert bytes back to string.

You can't just call input.read(arbytes) because the read function doesn't necessarily read the entire length of the array. You can do a loop where you read a chunk at a time but the code for that is a bit more complex.

Anyway, you get the idea.


Also, if you really want to control what goes in what packets, you can use Datagram Sockets, but if you do that then delivery of the packet is not guaranteed.

安静被遗忘 2024-08-20 04:22:25

套接字发送数据流,而不是消息。
您不应依赖收到的数据包与发送的数据包大小相同。
正如您所看到的,数据包可以组合在一起,但也可以分解。
使用 @Chad Okere 关于如何确保您获得的块与发送的块相同的建议。

但是,就您而言,您可以使用

dataOutputStream.writeUTF(ar); // sends a string as UTF-8

String text = dataInputStream.readUTF(); // reads a string as UTF-8

Socket send a stream of data, not messages.
You shouldn't rely on the packets you receive being the same size as they are sent.
Packets can be grouped together as you have seen but they can also be broken up.
Use @Chad Okere's suggestion on how to ensure you get blocks the same was they are sent.

However in your case, you can just use

dataOutputStream.writeUTF(ar); // sends a string as UTF-8

and

String text = dataInputStream.readUTF(); // reads a string as UTF-8
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文