How to send binary and text using the same socket

I need to send a short string in the form of text from the client to the server, and then after that send the binary file.

how can i send both binary and string using the same socket connection?

the server is a Java desktop application, and the client is an Android tablet. I already configured it to send text messages between the client and server in both directions. I have not completed the binary submission part yet.

One idea is to set up two separate servers at the same time. I think this is possible if I use two different port numbers and configure the servers to two different threads in the application. and I will need to configure two simultaneous clients running on two services in the Android application.

another idea is to somehow use the if else statement to determine which of the two file types is sent, or the binary text, and use the appropriate method to get the file for the file type to send.

sample code for sending text

PrintWriter out; BufferedReader in; out = new PrintWriter(new BufferedWriter (new OutputStreamWriter(Socket.getOutputStream())) true,); in = new BufferedReader(new InputStreamReader(socket.getInputStream())); out.println("test out"); String message = in.readLine(); 

sample code to send a binary file

  BufferedOutputStream out; BufferedInputStream in; byte[] buffer = new byte[]; int length = 0; out = new BufferedOutputStream(new FileOutputStream("test.pdf)); in = new BufferedInputStream(new FileOutputStream("replacement.pdf")); while((length = in.read(buffer)) > 0 ){ out.write(buffer, 0, length); } 
+6
source share
3 answers

I do not think that using two threads would be necessary in your case. Just use socket InputStream and OutputStream to send binary data after sending text messages.

Server code

 OutputStream stream = socket.getOutputStream(); PrintWriter out = new PrintWriter( new BufferedWriter( new OutputStreamWriter(stream) ) ); out.println("test output"); out.flush(); // ensure that the string is not buffered by the BufferedWriter byte[] data = getBinaryDataSomehow(); stream.write(data); 

Client code

 InputStream stream = socket.getInputStream(); String message = readLineFrom(stream); int dataSize = getSizeOfBinaryDataSomehow(); int totalBytesRead = 0; byte[] data = new byte[dataSize]; while (totalBytesRead < dataSize) { int bytesRemaining = dataSize - totalBytesRead; int bytesRead = stream.read(data, totalBytesRead, bytesRemaining); if (bytesRead == -1) { return; // socket has been closed } totalBytesRead += bytesRead; } 

To determine the correct dataSize -side dataSize , you must somehow pass the size of the binary block. You can send it as a string right before out.flush() to the server code or make it part of your binary data. In the latter case, the first four or eight bytes may contain the actual length of the binary data in bytes.

Hope this helps.


Edit

As @EJP correctly pointed out, using the BufferedReader on the client side is likely to corrupt or missing binary data, because the BufferedReader "steals" a few bytes from the binary data to fill its buffer. Instead, you should read the string data yourself and either look for the delimiter or the length of the string data passed by other means.

 /* Reads all bytes from the specified stream until it finds a line feed character (\n). * For simplicity sake I'm reading one character at a time. * It might be better to use a PushbackInputStream, read more bytes at * once, and push the surplus bytes back into the stream... */ private static String readLineFrom(InputStream stream) throws IOException { InputStreamReader reader = new InputStreamReader(stream); StringBuffer buffer = new StringBuffer(); for (int character = reader.read(); character != -1; character = reader.read()) { if (character == '\n') break; buffer.append((char)character); } return buffer.toString(); } 
+5
source

You can read about how the HTTP protocol works, which essentially sends the headers "ascii and human readable" (so to speak), and after that any content can be added with the appropriate encoding, for example base64. You can also create similar ones.

0
source

You need to send String first, then the size of the byte array, and then the byte array, use the String.startsWith() method to check what is being sent.

0
source

Source: https://habr.com/ru/post/953291/


All Articles