DataOutputStream not flushing

狂风中的少年 提交于 2019-12-23 04:47:47

问题


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?


回答1:


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.




回答2:


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.




回答3:


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


来源:https://stackoverflow.com/questions/1852232/dataoutputstream-not-flushing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!