简体   繁体   中英

Java - How to send efficiently binary data between string over socket?

I am making a chat program in which I have to separate a file into 1024 Bytes chunk and send it over Socket in this format:

<DataPacket>Binary_data<DataPacket\>

Currently, my only idea is to send a string

"<Packet>"

then a Byte[1024] and then a string

"<Packet\>".

So my question is:

  • Is there a more convenience way to do this?

  • Which Java class for input/output (DataInputStream, BufferedOutputStream,... ) is most suitable and a small example code of doing this?

Additional Info:

  • I must use Java library (JRE8), no Apache,...

  • I understand that I dont have to separate the data in TCP, it just be a must.

  • It would be very good if all the code can be run from a function like:

     void SendFile(Socket sendingSocket, File fileToSend); void ReceiveFile(Socket receivingSocket); 

To chunk binary data, it's usually better to send the number of bytes first and then the raw data as bytes. So your chat client should send the string "Packet 711\\n" first, then 711 bytes of the file (most file sizes are not multiples of 1024!).

That way, you can send the data in chunks and make the last chunk as small as necessary in order to avoid to corrupt the file. The line feed after the size makes it easier for the recipient to determine where the number ends and where the real raw data starts.

[EDIT] If you can't change the protocol much, maybe this works: <DataPacket>711\\n ... 711 bytes binary data ... </DataPacket>

So the code to send the data would look like this:

void SendFile(Socket sendingSocket, File fileToSend) {
    OutputStream stream = sendingSocket.getOutputStream();
    InputStream input = new FileInputStream(fileToSend);

    byte[] buffer = new byte[1024];
    int len;
    while(true) {
        len = input.read(buffer);
        if(len < 0) break;

        String header = "<DataPacket>" + len + "\n";
        stream.write(header.getBytes('ASCII'));
        stream.write(buffer, 0, len);
        String footer = "<DataPacket\>";
        stream.write(footer.getBytes('ASCII'));
    }

    input.close();
    stream.close();
}

On the receiving side, you need to parse the header (which includes the number of bytes to expect). Then you can allocate a buffer and read the bytes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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