10
public class SerProg {


    static ServerSocket ser=null;
    static Socket cli=null;
    static ObjectInputStream ins=null;
    static ObjectOutputStream outs=null;


    public static void main(String[] args) {

        try {

            ser=new ServerSocket(9000,10);
            cli=ser.accept();

            System.out.println("Connected to :"+cli.getInetAddress().getHostAddress()+" At Port :"+cli.getLocalPort());

            ins=new ObjectInputStream(cli.getInputStream());
            outs=new ObjectOutputStream(cli.getOutputStream());

            String str=(String)ins.readObject();


        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }


    }

}

And the Client

public class SerProg {

    /**
     * @param args
     */
    static ServerSocket ser=null;
    static Socket cli=null;
    static ObjectInputStream ins=null;
    static ObjectOutputStream outs=null;


    public static void main(String[] args) {
        // TODO Auto-generated method stub

        try {

            ser=new ServerSocket(9000,10);
            cli=ser.accept();

            System.out.println("Connected to :"+cli.getInetAddress().getHostAddress()+" At Port :"+cli.getLocalPort());

            ins=new ObjectInputStream(cli.getInputStream());
            outs=new ObjectOutputStream(cli.getOutputStream());

            String str=(String)ins.readObject();


        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }


    }

}

The Connection is established successfully but in the Server Code Line

ins=new ObjectInputStream(cli.getInputStream());

the code halts and does not proceed,what might be the problem ??

user207421
  • 289,834
  • 37
  • 266
  • 440
Abhishek
  • 308
  • 4
  • 15

2 Answers2

35

You need to create the ObjectOutputStream before the ObjectInputStream at both sides of the connection(!). When the ObjectInputStream is created, it tries to read the object stream header from the InputStream. So if the ObjectOutputStream on the other side hasn't been created yet there is no object stream header to read, and it will block indefinitely.

Or phrased differently: If both sides first construct the ObjectInputStream, both will block trying to read the object stream header, which won't be written until the ObjectOutputStream has been created (on the other side of the line); which will never happen because both sides are blocked in the constructor of ObjectInputStream.

This can be inferred from the Javadoc of ObjectInputStream(InputStream in):

A serialization stream header is read from the stream and verified. This constructor will block until the corresponding ObjectOutputStream has written and flushed the header.

This is also described in section 3.6.2 of Fundamental networking in Java by Esmond Pitt.

Mark Rotteveel
  • 82,132
  • 136
  • 114
  • 158
  • I don't understand why the order is relevant between ObjectOutputStream and ObjectInputStream – benjarobin Jan 01 '13 at 13:55
  • 4
    @benjarobin If both sides first construct the `ObjectInputStream`, both will block trying to read the object stream header, which won't be written until the `ObjectOutputStream` has been created (on the other side of the line); which will never happen because both sides are blocked in the constructor of `ObjectInputStream`. – Mark Rotteveel Jan 01 '13 at 13:58
  • 1
    Sorry I misunderstood you message, sorry !!! You comment is very clear, you should add it in your answer. I didn't understand that both client and server are sending in both direction object (my bad) You gain +1 from me :-) – benjarobin Jan 01 '13 at 14:00
  • I've seen many duplicate questions to this one, which all have the same answer, unfortunately this solution doesn't work for me, do you have any other suggestions for me ? – BHA Bilel Apr 04 '21 at 19:11
  • @danibilel In some implementations it may be necessary to explicitly call `flush()` on the `ObjectOutputStream` immediately after creation **before** you create the `ObjectInputStream`. However, in all cases you must construct the out before the in on both sides to prevent mutual waiting. – Mark Rotteveel Apr 04 '21 at 19:36
  • Thanks for your response, my case was more sophisticated than establishing a client/server connection, i fixed it by re-instantiating the serversocket. – BHA Bilel Apr 04 '21 at 20:27
-1

You must make handshaking for streams. I mean that in client side, when you create a object input stream you must create a object output stream in server side.

//SERVER SIDE
Socket clientSocket = TcpServer.socket.accept();
// 1. input stream;
ObjectInputStream sInput = new ObjectInputStream(clientSocket.getInputStream());
// 2. output stream
ObjectOutputStream sOutput = new ObjectOutputStream(clientSocket.getOutputStream());


//CLIENT SIDE
Socket socket = new Socket(ip, port);
// 2. output stream
ObjectOutputStream sOutput = new (socket.getOutputStream());
// 1. input stream
ObjectInputStream sInput = new ObjectInputStream(socket.getInputStream());

I tried to show that how to make handshaking for streams.

samet kaya
  • 69
  • 3
  • It doesn't have to be the client end that creates the `ObjectOutputStream` first: it can be either end, but it is safest to create it first at *both* ends. Then you can't have a problem. – user207421 Nov 13 '20 at 23:59