Java OutputStream only clears data when closing

Socket socket = new Socket("192.168.178.47", 82); OutputStream out = socket.getOutputStream(); out.write("{ \"phone\": \"23456789\" }".getBytes()); out.flush(); 

//Server

 InputStream in = client.getInputStream(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); int i = 0; while((i = in.read()) >= 0) { bOut.write(i); } String complete = new String(bOut.toByteArray(), "UTF-8"); 

I tried sending data through an OutputStream to a socket, but the data is not washed away. If I add out.close(); in the end, then it works fine, but the socket is closed, and I can not accept the answer. Does anyone know why? The server does not give any errors. I used Java 1.7!

+7
java outputstream sockets
source share
6 answers

Perhaps the server is waiting for the end of the line. If so, add "\ n" to the text

+6
source share

I am not sure about the "// Server" marking in your question, but I assume the following code is the server code:

 InputStream in = client.getInputStream(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); int i = 0; while((i = in.read()) >= 0) { bOut.write(i); } String complete = new String(bOut.toByteArray(), "UTF-8"); 

This will continue, blocking each time until it receives a value from read() less than zero. This only happens if the stream is closed.

It looks like you need to create your own protocol. Therefore, instead of searching "<= 0", find some constant value that signals the completion of the message.

Here's a quick demonstration of what I mean (I didn't have time yesterday). I have 3 classes, Message , MyClient (also the main class) and MyServer . Please note that there is no information about sending or receiving a new line. TcpNoDelay sets nothing. But it works great. Some other notes:

  • This code sends and receives only one request and response.
  • It does not support sending multiple instances of Message . This will require checking the beginning of Message as well as the end.

Message class:

 public class Message { public static final String MSG_START = "<message>"; public static final String MSG_END = "</message>"; private final String content; public Message(String string){ content = string; } @Override public String toString(){ return MSG_START + content + MSG_END; } } 

MyServer class

 public class MyServer implements Runnable{ public static final int PORT = 55555; @Override public void run(){ try { ServerSocket serverSocket = new ServerSocket(PORT); Socket socket = serverSocket.accept(); String message = getMessage(socket); System.out.println("Server got the message: " + message); sendResponse(socket); }catch (IOException e){ throw new IllegalStateException(e); } } private void sendResponse(Socket socket) throws IOException{ Message message = new Message("Ack"); System.out.println("Server now sending a response to the client: " + message); OutputStream out = socket.getOutputStream(); out.write(message.toString().getBytes("UTF-8")); } private String getMessage(Socket socket) throws IOException{ BufferedInputStream in = new BufferedInputStream(socket.getInputStream()); StringBuilder sb = new StringBuilder(100); byte[] bytes = new byte[1024<<8]; while(sb.lastIndexOf(Message.MSG_END) == -1){ int bytesRead = in.read(bytes); sb.append(new String(bytes,0,bytesRead,"UTF-8")); } return sb.toString(); } } 

MyClient class

 public class MyClient { public static void main(String[] args){ MyClient client = new MyClient(); Thread server = new Thread(new MyServer()); server.start(); client.performCall(); } public void performCall(){ try { Socket socket = new Socket("127.0.0.1",MyServer.PORT); sendMessage(socket, "Why hello there!"); System.out.println("Client got a response from the server: " + getResponse(socket)); } catch (IOException e) { throw new IllegalStateException(e); } } public String getResponse(Socket socket) throws IOException{ String response; StringBuilder sb = new StringBuilder(100); InputStream in = socket.getInputStream(); byte[] bytes = new byte[1024]; while(sb.lastIndexOf(Message.MSG_END) == -1){ int bytesRead = in.read(bytes); sb.append(new String(bytes,0,bytesRead,"UTF-8")); } response = sb.toString(); return response; } public void sendMessage(Socket socket, String message) throws IOException{ Message msg = new Message(message); System.out.println("Client now sending message to server: " + msg); OutputStream out = socket.getOutputStream(); out.write(msg.toString().getBytes("UTF-8")); } } 

Exit

  Client now sending message to server: Why hello there!
 Server got the message: Why hello there!
 Server now sending a response to the client: Ack
 Client got a response from the server: Ack

 Process finished with exit code 0 
+3
source share

Try using

 socket.setTcpNoDelay(true); 

There is buffering that occurs for performance reasons (read the Nagle algorithm).

+1
source share

Looking at your code, everything looks fine. However, you send less than MTU. Nagle algothrim can hold it until there is enough data for the full packet or you close the socket.

So - try the following:

 socket.setTCPNoDelay(true); 

http://en.wikipedia.org/wiki/Nagle%27s_algorithm https://docs.oracle.com/javase/8/docs/api/java/net/Socket.html#setTcpNoDelay-boolean-

0
source share

This is a server problem because flush always forces you to write. to test it, try running this code:

 public static void main(String[] args) throws IOException, InterruptedException { Socket socket = new Socket("localhost", 8222); OutputStream out = socket.getOutputStream(); for (int i = 0; i < 10; i++) { out.write((i + " : { \"phone\": \"23456789\" }").getBytes()); out.flush(); TimeUnit.SECONDS.sleep(1); } } 

run this command in the shell:

 $ nc -l localhost 8222 

who are listening on port 8222 for data. you will see that every 1 second the data will be displayed on the output of nc

0
source share

The problem is not that you are cleaning up incorrectly, but that the read code expects the socket to disconnect before processing the data:

while((i = in.read()) >= 0)

There will be a loop, while something can be read from in (socket InputStream). The condition will not work until the other partner disconnects.

0
source share

All Articles