niceman
niceman

Reputation: 2673

ObjectStreams with sockets hang at server and client side java

I have this code :

package com.company;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.ServerSocket;
import java.net.Socket;

class MyClass implements Serializable
{
    private int i,j;

    public MyClass(int i, int j)
    {
        this.i = i;
        this.j = j;
    }

    public int getJ()
    {
        return j;
    }

    public void setJ(int j)
    {
        this.j = j;
    }

    public int getI()
    {
        return i;
    }

    public void setI(int i)
    {
        this.i = i;
    }
}
class ServerThread extends Thread
{
    ServerSocket server;

    public ServerThread() throws IOException
    {
        server=new ServerSocket(14200);
    }

    @Override
    public void run()
    {
        try
        {
            Socket client=server.accept();
            ObjectInputStream in=new ObjectInputStream(client.getInputStream());
            ObjectOutputStream out=new ObjectOutputStream(client.getOutputStream());
            int i=in.readInt();
            MyClass m=(MyClass)in.readObject();
            if(i==m.getI())
            {
                m.setJ(i);
                out.writeObject(m);
            }
            else
            {
                m.setI(i);
                out.writeObject(m);
            }
            out.writeUTF("see ya");
        }
        catch (IOException | ClassNotFoundException e)
        {
            e.printStackTrace();
        }
    }
}
public class Main
{
    public static void main(String... args) throws IOException, ClassNotFoundException
    {
        ServerThread serverThread=new ServerThread();
        serverThread.setDaemon(true);
        serverThread.start();
        Socket client=new Socket("localhost",14200);
        ObjectInputStream in=new ObjectInputStream(client.getInputStream());
        ObjectOutputStream out=new ObjectOutputStream(client.getOutputStream());
        out.writeInt(2);
        out.writeObject(new MyClass(4,2));
        MyClass m=(MyClass)in.readObject();
        String s=in.readUTF();
        System.out.println(s);
    }
}

My problem is that both client and server hang on this line :

ObjectInputStream in=new ObjectInputStream(client.getInputStream);  

If I set timeout for the sockets I get SocketTimeoutException.

Real Goal

The program above is just a dummy program but shows my issue, the real program is a server-client application for sharing files in which I implemented my own simple protocol, it's a homework actually.

We are asked to implement digital signature, I made my own helper classes and I ended up with SignatureWithPublicKey class(defined by me) which holds the signature bytes and the public key, I need to send this object across socket.

A simple solution would be to send PublicKey.getEncoded along with the signature bytes But I want to use ObjectStreams, I need to know why aren't they working.

So what's the issue here ?

Upvotes: 1

Views: 213

Answers (1)

Peter Lawrey
Peter Lawrey

Reputation: 533442

The Object stream has a small header. This means you can't even start an object input stream until the header has been sent and read. However your code doesn't send the header until you call ObjectOutputStream which in this case you are doing AFTER the input stream. i.e. you have a dead lock.

In short, swap the order of the new ObjectInputStream and new ObjectOutputStream in both cases.

Upvotes: 3

Related Questions