0

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);
    
2
  • You could send the SOH char to signify start and ETX to signal the end of the message, but ultimately if youre going to define your own protocol, use what you want. Commented Oct 23, 2014 at 15:37
  • @MarkW Does use SOH and ETX will help the Stream reader distinguish between the header and the data or is just make writing parsing code easier? Commented Oct 23, 2014 at 15:49

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

6 Comments

Sorry, but this is not my own protocol so I can only write Java code to implement it. But I have a question, I thought I would just append whatever between two header "<Packet>" together, so how can it corrupt the file? Isn't TCP guarantee this?
What happens when the file contains the strings "<Packet>" or "</Packet>"? What happens then the file length is 15 bytes?
In the paper stated that if there is a "<" or ">" in the content (chat message, data) change it to "<<" and ">>" and vice versa. But I guess you're right, check the data for "<" in a byte array wouldbe a pain. But "What happens then the file length is 15 bytes?"?, ain't it just send that byte[15] between two strings?
That depends on the code you write. If you blindly send byte[1024], it will always be 1024 bytes.
Thank you! As I check the available size of file before put it into array, I think the len can be omitted. Let me test some files if it is OK.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.