tags:

views:

266

answers:

4

Hi folks!

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

+2  A: 

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.

bmargulies
RMI is very expensive. Sometimes, streams + sockets are a better solution.
Koder_
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.
Adrian Pronk
+1  A: 

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

Stephen C
even if I change the order the client simply stops. The response is optional... if there's no response it keeps waiting.
wishi
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?
PSpeed
@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.
Stephen C
+2  A: 

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

Karussell
+1  A: 

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.

Sam Barnum