尝试通过套接字发送对象时应用程序冻结

时间:2015-10-25 17:28:51

标签: java sockets serialization objectinputstream objectoutputstream

让我直接进入。这是我的服务器类:

public class DTServer {

ServerSocket serverSocket;
ServerSocketHints serverSocketHints;
Socket socket;
InputStream inputStream;
OutputStream outputStream;
ObjectInputStream objectInputStream;
ObjectOutputStream objectOutputStream;

public DTServer(int port) {
    serverSocketHints = new ServerSocketHints();
    serverSocketHints.acceptTimeout = 0;

        serverSocket = Gdx.net.newServerSocket(
                Net.Protocol.TCP, port, serverSocketHints);

    socket = serverSocket.accept(null);
}

public Serialized receiveSerialized() {
    inputStream = socket.getInputStream();
    try {
        objectInputStream = new ObjectInputStream(inputStream);
    } catch (IOException e) {
        e.printStackTrace();
    }

    outputStream = socket.getOutputStream();
    try {
        objectOutputStream = new ObjectOutputStream(outputStream);
    } catch (IOException e) {
        e.printStackTrace();
    }

    Serialized serialized = new Serialized();
    try {
        serialized = (Serialized) objectInputStream.readObject();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return serialized;
}
}

客户端类:

public class DTClient {

Socket socket;
SocketHints socketHints;
InputStream inputStream;
OutputStream outputStream;
ObjectInputStream objectInputStream;
ObjectOutputStream objectOutputStream;

public DTClient(String address, int port) {
    socketHints = new SocketHints();
    socketHints.connectTimeout = 3000;
    socketHints.keepAlive = true;
//        socketHints.trafficClass = 0x04; //IPTOS_RELIABILITY

    socket = Gdx.net.newClientSocket(
            Net.Protocol.TCP, address, port, socketHints);
}

public void sendSerialized(Serialized serialized) {
    inputStream = socket.getInputStream();
    try {
        objectInputStream = new ObjectInputStream(inputStream);
    } catch (IOException e) {
        e.printStackTrace();
    }

    outputStream = socket.getOutputStream();
    try {
        objectOutputStream = new ObjectOutputStream(outputStream);
    } catch (IOException e) {
        e.printStackTrace();
    }

    try {
        objectOutputStream.writeObject(serialized);
    } catch (IOException e) {
        e.printStackTrace();
    }
}
}

我像这样创建服务器对象:

public void startServer() {
    new Thread(new Runnable() {
        @Override
        public void run() {
            dtServer = new DTServer(32658);
            System.out.println("Server started and listening at port: 32658.");
        }
    }).start();
}

然后使用该程序的其他实例连接到它:

public void connect() {
    new Thread(new Runnable() {
        @Override
        public void run() {
            dtClient = new DTClient("127.0.0.1", 32658);
            System.out.println("Connected to server at 127.0.0.1:32658");

        }
    }).start();
}

在我尝试接收我发送的对象之前,所有工作都会膨胀:

game.dtClient.sendSerialized(new Serialized(game.gameScreen.localPlayer));
//client side

Serialized s = (Serialized)game.dtServer.receiveSerialized();
//server side

调用receiveSerialized方法会导致两个应用程序实例冻结。

1 个答案:

答案 0 :(得分:0)

在两端的ObjectOutputStream之前创建ObjectInputStream,。否则,您可能会遇到尝试读取对象流标题的死锁。

您还应该在套接字的生命周期中使用相同的对象流,而不是每条消息使用一对新对象。