1

I have written an EchoServer that responds with the String ack if the data have been send accordingly.

My client looks like this... In order to receive the ack answer from the server the "echoSocket" puts the received data into in, my ObjectInputStream. Only if I comment these parts out the client works

        echoSocket = new Socket(server_name, tcp_port);
        System.out.println(" *** Connected to " + server_name  + " ***");
        System.out.println("Press Enter to send your message.");

        out = new ObjectOutputStream(echoSocket.getOutputStream());
        in = new ObjectInputStream(echoSocket.getInputStream());

        out.flush();

        String message = System.console().readLine();

        while(!message.equals("quit")) {


            // problem                
            if (in.readObject().equals(ack)) 
                System.out.println("ACKed");
            in.close();
            // problem ends
            out.flush();

            out.writeObject(message);
            System.out.println("Sending: " + message);      
            message = System.console().readLine();
            out.flush();

        }

Does anybody know why it won't send my Strings?

Thanks, Marius

1
  • Is ack meant to be a string literal? Change to: if (in.readObject().equals("ack")) Commented Nov 23, 2009 at 1:23

4 Answers 4

3

Using object streams over sockets is not really a recommended idea. You might consider a full web service, or RMI.

It might work better if you read into a buffer and make sure that you have the whole business before trying to deserialize with the object streams.

Sign up to request clarification or add additional context in comments.

2 Comments

RMI is very expensive. Sometimes, streams + sockets are a better solution.
It won't work better if you read into a buffer - then you'll have to manage object boundaries yourself. But inserting a BufferedInputStream will mean fewer calls to the OS-level read system call. Tests like this often fail due to blocking that occurs when trying to read and write the same channel in the same thread.
2

Why not use hessian library?

It works like a charm: http://karussell.wordpress.com/2009/04/10/hessian-web-service-protocol-hello-world-example/

Or try spring remoting (which is not that lightweight)

http://static.springsource.org/spring/docs/2.5.x/reference/remoting.html

Comments

1

It looks like the client is trying to read the acknowledgement before it has written the message.

3 Comments

even if I change the order the client simply stops. The response is optional... if there's no response it keeps waiting.
readObject() will block until data is received. So if the server never acknowledges then you will wait forever. You say the ACK is optional... maybe you can expand on why you want an ACK if it isn't required. How long should you wait for it before giving up? Why does this loop even care?
@wishi_ I suggest that you stop randomly moving things around and THINK about what is going on. As @PSpeed says, calling a read operation on the client's input stream will cause it to block until it receives the data (optional or not) from the server.
1

Split the "sending" and "receiving" code into separate threads, the writer thread can write to the socket while your other thread is blocked on the call to readObject().

If this is going to be a long-running client, I'd also recommend using the lower-level DataInputStream and DataOutputStream instead of ObjectInputStream / ObjectOutputStream, to prevent holding onto a possibly large IdentityHashmap of the objects.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.