Opening read / write streams multiple times from Socket

In the class where I have a ServerSocket to listen for incoming connections, below is the code:

 while(isRunning) { try { Socket s = mysocketserver.accept(); acknowledgeClient(s); new ClientHandler(s).start(); //Start new thread to serve the client, and get back to accept new connections. } catch(Exception ex) { ex.printStackTrace(); } } 

And the following code is acknowledgeClient(Socket s) .

 ObjectInputStream in = new ObjectInputStream(s.getInputStream); ObjectOutputStream out = new ObjectOutputStream(s.getOutStream); String msg = in.readObject().toString(); System.out.println(msg+" is Connected"); //Show who connected out.writeObject("success"); //Respond with success. in.close(); out.close(); 

The run() ClientHandler .

 try { in = new ObjectInputStream(client.getInputStream()); out = new ObjectOutputstream(client.getOutputStream()); String msg = ""; while(!msg.equalsIgnoreCase("bye")) { msg = in.readObject().toString(); System.out.println("Client Says - "+msg); out.writeObject("success"); } in.close(); out.close(); } catch(Exception ex) { ex.printStackTrace(); } 

And as follows, how the client program interacts with this Echo Server.

 try { int count = 10; client = new Socket("localhost",8666); in = new ObjectInputStream(client.getInputStream()); out = new ObjectOutputstream(client.getOutputStream()); out.writeObject("Foo"); System.out.println("Connection Status : "+in.readObject().toString()); while(count>0) { out.writeObject("Hello!"); String resp = in.readObject().toString(); //Getting EOFException here. System.out.println("Sent with :"+resp); count--; Thread.sleep(1000); } out.close(); in.close(); client.close(); } catch(Exception ex) { ex.printStackTrace(); } 

As you can see, after the client has been confirmed after the connection, I close the read / write streams and from the new stream serving the client, I open the stream again and read / write from the connected socket from the server, but as soon as I try to read server response when sending Hello! by the client, it will EOFException instead of receiving success .

I know the reasons why EOF happens, but not understanding why this is happening here, I am not trying to read a socket that has nothing in its stream (it should have success , as written by the server).

It is too early for the client to try to read the socket before the server prints Hello! at its end and wrote success as an answer?

PS: I know that this is not a good way to ask a question by putting so much code, we expect that here we will get answers to this problem and understand this, and not eliminate our problem by others and make sure. So, I have provided this code to show all aspects of the problem.

+4
source share
4 answers

I studied the source code of ObjectInputStream, and it seems that the reference to the source input stream s.getInputStream() is stored inside ObjectInputStream.

When you close ObjectInputStream, s.getInputStream() also closes.

Once the input stream is closed, it cannot be opened again. This way you get an EOFException that indicates that you are at the end of the stream (since the stream cannot be reopened).

You should do something similar to confirm the customer.

Inside the run () method of ClientHandler:

 try { // acknowledge client ObjectInputStream in = new ObjectInputStream(s.getInputStream()); ObjectOutputStream out = new ObjectOutputStream(s.getOutStream()); String msg = in.readObject().toString(); System.out.println(msg+" is Connected"); //Show who connected out.writeObject("success"); //Respond with success. // end acknowledge client String msg = ""; while(!msg.equalsIgnoreCase("bye")) { msg = in.readObject().toString(); System.out.println("Client Says - "+msg); out.writeObject("success"); } in.close(); out.close(); } catch(Exception ex) { ex.printStackTrace(); } 

If you want to isolate the confirmation code in a separate method, just be sure to save the correct link to the same ObjectInputStream without closing the stream, and then pass the link around.

+5
source

I open the stream again, and the server starts reading / writing from the connected socket,

Once the stream is close, you cannot open it again. In fact, you cannot use two streams of objects in one stream this way at all.

Instead, you should create a stream of objects for input and output once and only once and do not close it until you are done.

+1
source

Take a good look at this program, I wrote it to understand several clients and communicate with the server, your question was answered in this program.

Client code

 public class ClientWala { public static void main(String[] args) throws Exception{ Boolean b = true; Socket s = new Socket("127.0.0.1", 4444); System.out.println("connected: "+s.isConnected()); OutputStream output = s.getOutputStream(); PrintWriter pw = new PrintWriter(output,true); // to write data to server while(b){ if (!b){ System.exit(0); } else { pw.write(new Scanner(System.in).nextLine()); } } // to read data from server InputStream input = s.getInputStream(); InputStreamReader isr = new InputStreamReader(input); BufferedReader br = new BufferedReader(isr); String data = null; while ((data = br.readLine())!=null){ // Print it using sysout, or do whatever you want with the incoming data from server } } } 

Server code

 public class ServerTest { ServerSocket s; public void go() { try { s = new ServerSocket(44457); while (true) { Socket incoming = s.accept(); Thread t = new Thread(new MyCon(incoming)); t.start(); } } catch (IOException e) { e.printStackTrace(); } } class MyCon implements Runnable { Socket incoming; public MyCon(Socket incoming) { this.incoming = incoming; } @Override public void run() { try { PrintWriter pw = new PrintWriter(incoming.getOutputStream(), true); InputStreamReader isr = new InputStreamReader( incoming.getInputStream()); BufferedReader br = new BufferedReader(isr); String inp = null; boolean isDone = true; System.out.println("TYPE : BYE"); System.out.println(); while (isDone && ((inp = br.readLine()) != null)) { System.out.println(inp); if (inp.trim().equals("BYE")) { System.out .println("THANKS FOR CONNECTING...Bye for now"); isDone = false; s.close(); } } } catch (IOException e) { // TODO Auto-generated catch block try { s.close(); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } e.printStackTrace(); } } } public static void main(String[] args) { new ServerTest().go(); } } 
0
source

Closing any input stream or output stream or reader or write around a socket stream closes the socket and implies other streams, readers and writers.

Use the same streams, readers, writers for socket life.

0
source

All Articles