ObjectInputStream (socket.getInputStream ()); does not work


I am programming a class to communicate with the server, but when it tries to build an ObjectInputStream using an input stream, the program freezes. Theres no exception, and the program still works, but hangs on the line where it is trying to build an ObjectInputstream.

Here is the method code where my problem is located:

@Override public void connect(String ip, int port) throws UnknownHostException, IOException { Socket socket = new Socket(ip, port); out = new ObjectOutputStream(socket.getOutputStream()); InputStream is = socket.getInputStream(); in = new ObjectInputStream(is); } 

and this is the code for the whole class:

 package Client; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.PrintWriter; import java.net.Socket; import java.net.UnknownHostException; public class MessageStreamerImpl implements MessageStreamer { ObjectOutputStream out; ObjectInputStream in; public MessageStreamerImpl(String ip, int port) throws UnknownHostException, IOException{ connect(ip, port); } public MessageStreamerImpl(){ } @Override public void send(Object message) throws IOException { if(out == null) throw new IOException(); out.writeObject(message); out.flush(); } @Override public Object receive() throws IOException{ try { return in.readObject(); } catch (ClassNotFoundException e) { throw new IOException(); } } @Override public void connect(String ip, int port) throws UnknownHostException, IOException { Socket socket = new Socket(ip, port); out = new ObjectOutputStream(socket.getOutputStream()); InputStream is = socket.getInputStream(); in = new ObjectInputStream(is); } } 

When looking at Google, I found this: http://www.coderanch.com/t/232944/threads/java/Socket-getInputStream-block . But I still do not know how to solve the problem, because my ObjectOutputStream constructor is located before the ObjectInputStream object.

Here is my server code, maybe it will help;)

 package Server; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketException; import java.util.ArrayList; public class Server { ArrayList<Socket> clients = new ArrayList<Socket>(); public Server(int port){ try { ServerSocket mySocket = new ServerSocket(port); waitForClients(mySocket); } catch (IOException e) { System.out.println("Unable to start."); e.printStackTrace(); } } private void waitForClients(ServerSocket mySocket) { while(true){ try { System.out.println("Ready to receive"); Socket client = mySocket.accept(); clients.add(client); System.out.println(client.getInetAddress().getHostAddress()+" connected to the Server"); Thread t = new Thread(new ClientHandler(client)); t.start(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public void shareToAll(Object objectToSchare){ for(Socket client:clients){ ObjectOutputStream oos; try { oos = new ObjectOutputStream(client.getOutputStream()); oos.writeObject(objectToSchare); oos.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } private class ClientHandler implements Runnable{ Socket clientSocket; public ClientHandler(Socket clientSocket){ this.clientSocket = clientSocket; } @Override public void run() { try { ObjectInputStream ois = new ObjectInputStream(clientSocket.getInputStream()); while(true){ try { ois.readObject(); } catch (ClassNotFoundException | IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }catch(SocketException e){ System.out.println(clientSocket.getInetAddress().getHostAddress()+" disconnected from the Server"); clients.remove(clientSocket); }catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } 

Thank you for your help. I found a mistake. This was in the server class, which should look like this:

 package Server; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketException; import java.util.ArrayList; public class Server { ArrayList<ObjectOutputStream> clientstreams = new ArrayList<ObjectOutputStream>(); public Server(int port){ try { ServerSocket mySocket = new ServerSocket(port); waitForClients(mySocket); } catch (IOException e) { System.out.println("Unable to start."); e.printStackTrace(); } } private void waitForClients(ServerSocket mySocket) { while(true){ try { System.out.println("Ready to receive"); Socket client = mySocket.accept(); clientstreams.add(new ObjectOutputStream(client.getOutputStream())); System.out.println(client.getInetAddress().getHostAddress()+" connected to the Server"); Thread t = new Thread(new ClientHandler(client)); t.start(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public void shareToAll(Object objectToSchare){ for(ObjectOutputStream stream:clientstreams){ try { stream.writeObject(objectToSchare); stream.flush(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } private class ClientHandler implements Runnable{ Socket clientSocket; public ClientHandler(Socket clientSocket){ this.clientSocket = clientSocket; } @Override public void run() { try { ObjectInputStream ois = new ObjectInputStream(clientSocket.getInputStream()); while(true){ try { ois.readObject(); } catch (ClassNotFoundException | IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }catch(SocketException e){ System.out.println(clientSocket.getInetAddress().getHostAddress()+" disconnected from the Server"); clientstreams.remove(clientSocket); }catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } 

Most of the changes you see with the waitForClients () method, but I also changed the concept of my ArrayList and the shareToAll method.

+7
source share
1 answer

the ObjectInputStream constructor reads data from the given InputStream. in order for this to work, you must clear the ObjectOutputStream immediately after creation (to record the initial header) before attempting to open the ObjectInputStream. also, if you want to send multiple objects to a single connection, you must open ObjectOutputStream once and use it for the life of the socket (for example, your shareToAll method).

+12
source

All Articles