简体   繁体   English

ObjectOutputStream方法writeObject挂在android上

[英]ObjectOutputStream method writeObject hangs on android

I write some client-server communication. 我写了一些客户端-服务器通信。

My server: 我的服务器:

public class Server {


    public synchronized static void sendPacket(Packet packet,
            ObjectOutputStream server) {

        try {
            server.writeObject(packet);
            server.flush();
        } catch (IOException e) {
            Log.d(TAG, "Error while sending a packet. Output stream is unaviable.");
        }
    }

    public synchronized static Packet readPacket(ObjectInputStream sourceStream) {
        Packet recivedPacket = null;
        try {
            recivedPacket = (Packet) sourceStream.readObject();
        } catch (StreamCorruptedException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
    } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        return recivedPacket;
    }


    /** Register user on the server */
    private User registerUser(Socket socket) {
        ClientUserLoginPacket newUserPacket = null;
        ObjectInputStream ois = null;
        ObjectOutputStream oos = null;
        try {
            Log.i(TAG, "Opening output stream...");
            oos = new ObjectOutputStream(socket.getOutputStream());
            if (oos != null)
                Log.d(TAG, "Output stream opened");

            Log.i(TAG, "Opening input stream...");
            ois = new ObjectInputStream(socket.getInputStream());
            if (ois != null)
                Log.d(TAG, "Input stream opened");

        } catch (StreamCorruptedException e1) {
                Log.e(TAG, "Error while opening stream");
        } catch (IOException e1) {
            e1.printStackTrace();
        }

        // First packet MUST be register request
        try {
            Log.d(TAG, "Waiting for login packet from client...");
            newUserPacket = (ClientUserLoginPacket) readPacket(ois);
            Log.d(TAG, "Login packet from recived...");
        } catch (Exception e) {
            Log.e(TAG, "Can't recive login packet.");
        }
        User newUserInstance = null;
        // TODO check if exists. or to map in the future
        if (newUserPacket != null) {
            newUserInstance = new User(socket, ois, oos, newUserPacket.nick);
            users.add(newUserInstance);
            Log.d(TAG, "User " + newUserPacket.nick + " registered.");

            Server.sendPacket(new ServerLoginAcceptedPacket(), oos);
            Log.d(TAG, "User accept confirmation sent.");
        }
        return newUserInstance;
    }
    @Override
        public void run() {

            Log.i(TAG, "Starting server...");
            ServerSocket server;
            try {
                server = new ServerSocket(PORT);
                Log.i(TAG, "Server started.");
                server.setSoTimeout(0);

                while (true) {
                    Log.i(TAG, "Waiting for players...");
                    final Socket socket = server.accept();
                    Log.i(TAG, "New player connected.");
                    new Thread(new Runnable() {

                        @Override
                        public void run() {
                            Log.i(TAG, "Try to register new player.");
                            try {
                                Thread.sleep(1000);
                            } catch (InterruptedException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                            User user = registerUser(socket);
                            while (true) {

                                Log.i(TAG, "Waiting for packets from " + user.nick+"...");
                                Packet packet = readPacket(user.ois);
                                Log.i(TAG, "Packet from " + user.nick + " recived.");

                                if (packet instanceof ...) {
                                     ...
                                }
                            }
                        }

                    }).start();
                    }

            } catch (IOException e) {
                Log.i(TAG, "Port is busy.");
            }

        }


    private class User {
        public Socket connection;
        public ObjectInputStream ois;
        public ObjectOutputStream oos;
        public String nick;
        public boolean inGame;

        public User(Socket socket, ObjectInputStream ois,
                ObjectOutputStream oos, String nick) {
            this.connection = socket;
            this.ois = ois;
            this.oos = oos;
            this.nick = nick;
    }
    // ...
}

My client: 我的客户:

public class Client {
    callbackHandler = new Thread(new Runnable() {

        @Override
        public void run() {

            while (true) {

                Log.e(TAG, "Waiting for incomeing packets...");
                Packet packet = (Packet) Server.readPacket(serverInput);
                Log.e(TAG, "Packet recived.");

                if (packet instanceof ServerLoginAcceptedPacket) {
                    Log.e(TAG, "Recived packet is "
                            + packet.getClass().toString());
                    Intent intent = new Intent(MyActivity.this,
                            MainMenuActivity.class);

                    MyActivity.this.startActivity(intent);
                }
            }

        }
    });


    public void connectToServer() {

        SocketAddress sockaddr = new InetSocketAddress(mEditTextIp.getText()
                .toString(), Server.PORT);
        server = new Socket();
        try {
            server.setSoTimeout(1000);
            Log.d(TAG, "Connecting to server.");
            server.connect(sockaddr, Server.PORT);
            Log.d(TAG, "Connected to server.");
        } catch (IOException e) {
            Log.e(TAG, "Can't connect to server.");
            server = null;
        }

        if (server != null)
            try {
                server.setSoTimeout(0);
                Log.d(TAG, "Opening output stream...");
                serverOutput = new ObjectOutputStream(server.getOutputStream());
                if (serverOutput != null)
                    Log.d(TAG, "Output stream opened");
                else
                    Log.e(TAG, "Error while opening output stream");

            } catch (IOException e) {
                Log.e(TAG, "Server socket probably closed");
            }
    }

    public void requestLogin() {

        new Thread(new Runnable() {

            @Override
            public void run() {
                Log.e(TAG, "Sending login packet...");
                Server.sendPacket(new ClientUserLoginPacket(mEditTextLogin
                        .getText().toString(), ""), serverOutput); // TODO send
                                                                    // pass and
                                                                    // email
                Log.e(TAG, "Login packet send");
            }
        }).start();
    }

    public void authenticate(View v) {

        if (server == null)
            connectToServer();

        if (server != null) {

            requestLogin();

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            try {
                serverInput = new ObjectInputStream(server.getInputStream());
            } catch (StreamCorruptedException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (serverInput != null) {

                Log.e(TAG, "Start reciving callbacks...");
                callbackHandler.start();
            } else {
                Log.d(TAG, "Can't open input stream to server.");
            }
        }

    }

    public void runServer(View v) {
        new Thread(new Server()).start();

            Toast.makeText(this, "Server running...", 1000).show();
    }
}

Where runServer() and authenticate() functions are triggered with button. 用按钮触发runServer()authenticate()函数。

Problem is that after server recive ClientLoginPacket , all subsequent sentPacket functions hangs on oos.writeObject() . 问题是服务器接收到ClientLoginPacket ,所有后续sentPacket函数都将挂在oos.writeObject()

I think the order of reading/writing from/to streams may be wrong. 我认为从/向流读取/写入的顺序可能是错误的。 What should be correct order of opening streams and writing objects to them? 打开流并向其中写入对象的正确顺序应该是什么? Do I have to write something to ObjectOutputStream before opening ObjectInputStream ? 打开ObjectInputStream之前是否必须向ObjectOutputStream写一些东西?

After few hours I found that keywords synchronized before my methods readPacket() and sendPacket() were problem. 几个小时后,我发现在方法readPacket()sendPacket()出现问题之前,关键字已synchronized ;) ;)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Android中的TCP-ObjectOutputStream writeObject失败 - TCP in Android - ObjectOutputStream writeObject failure ObjectOutputStream .writeObject - ObjectOutputStream .writeObject 返回空文件的ObjectOutputStream writeObject()方法 - ObjectOutputStream writeObject() method returning empty file java.io.NotSerializableException :: ObjectOutputStream:writeObject方法 - java.io.NotSerializableException:: ObjectOutputStream: writeObject method 当两个客户端将对象发送到服务器时,ObjectOutputStream writeObject挂起 - ObjectOutputStream writeObject hangs when two clients send objects to server Java 的 ObjectOutputStream 的 writeObject() 方法如何处理数组? - How does Java's ObjectOutputStream's writeObject() method work for array? 反序列化使用ObjectOutputStream的writeObject方法序列化的对象 - Deserializing an Object that has been serialized using ObjectOutputStream's writeObject method ObjectOutputStream的writeObject方法使用什么字符编码? - What character encoding does ObjectOutputStream 's writeObject method use? ObjectOutputStream的对象如何调用Serializable对象的私有writeObject方法 - How private writeObject method of Serializable object called by object of ObjectOutputStream 如何模拟objectOutputStream.writeObject()? - How to mock objectOutputStream.writeObject()?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM