Android SocketException' Socket已关闭'即使在使用了socket.isClosed()之后也关闭了

时间:2014-06-27 19:07:17

标签: java android sockets socketexception

我有一个应用程序,其中我使用套接字来侦听来自服务器的消息,它有两个活动,每个活动都有自己的方法来处理消息。

当我从第一个开始第二个时,我关闭该活动的套接字监听器并在第二个活动onCreate方法中启动一个新监听器。但是,当我切换活动时,我收到java.net.SocketException: Socket is closed错误。

public synchronized void run(){
    //Check if the thread has been shut down
    while(!this.stopped){
        socket = null;
        try{
            //Socket
            socket = new DatagramSocket(port);
            //Packet
            byte[] data = new byte [1024];
            DatagramPacket packet = new DatagramPacket(data, data.length);
            if(!socket.isClosed()){
                //Store data from socket into packet
                socket.receive(packet);
                //Create a string from the data
                String received = new String(packet.getData(),packet.getOffset(),packet.getLength());

                //Log the string TODO remove this
                Log.i("RECEIVED", received);

                //Get a new message object from the handler
                Message msg = commandHandler.obtainMessage();
                //Store the string in the message
                msg.obj = received;
                //Send the message to the handler
                commandHandler.sendMessage(msg);
            }

        }catch (IOException e) {
            e.printStackTrace();
        }finally{
            if(socket != null)
                socket.close();
        }
    }
}

/**
 * Close the listener
 */
public void shutDown(){
    this.stopped = true;
    if(socket != null){
        socket.close();
    }
}

从上面可以看出,我在收到消息之前使用!socket.isClosed()检查套接字是否已关闭

错误跟踪:

06-27 19:48:12.129: W/System.err(19460): java.net.SocketException: Socket closed
06-27 19:48:12.129: W/System.err(19460):    at libcore.io.Posix.recvfromBytes(Native Method)
06-27 19:48:12.129: W/System.err(19460):    at libcore.io.Posix.recvfrom(Posix.java:136)
06-27 19:48:12.129: W/System.err(19460):    at libcore.io.BlockGuardOs.recvfrom(BlockGuardOs.java:164)
06-27 19:48:12.129: W/System.err(19460):    at libcore.io.IoBridge.recvfrom(IoBridge.java:513)
06-27 19:48:12.129: W/System.err(19460):    at java.net.PlainDatagramSocketImpl.doRecv(PlainDatagramSocketImpl.java:161)
06-27 19:48:12.129: W/System.err(19460):    at java.net.PlainDatagramSocketImpl.receive(PlainDatagramSocketImpl.java:169)
06-27 19:48:12.129: W/System.err(19460):    at java.net.DatagramSocket.receive(DatagramSocket.java:253)
06-27 19:48:12.129: W/System.err(19460):    at com.android.homeservice.server.TabletListener.run(TabletListener.java:54)

更新

所以事实证明我在第二次活动中两次调用线程的start()方法,一次在onCreate中,再次在onStart中从之前遗留下来代码的版本。无论如何,谢谢你的所有答案,如果我浪费了你的时间,那就很抱歉

2 个答案:

答案 0 :(得分:1)

我建议重新架构。保持套接字处理所有线程,并告诉线程什么时候退出。当线程退出时,关闭套接字。

public synchronized void run(){
    //Check if the thread has been shut down
    Socket socket = new DatagramSocket(port);
    while(!this.stopped){
        socket = null;
        try{
            //Socket
            //Packet
            byte[] data = new byte [1024];
                //Store data from socket into packet
                socket.receive(packet);
                //Create a string from the data
                String received = new String(packet.getData(),packet.getOffset(),packet.getLength());

                //Log the string TODO remove this
                Log.i("RECEIVED", received);

                //Get a new message object from the handler
                Message msg = commandHandler.obtainMessage();
                //Store the string in the message
                msg.obj = received;
                //Send the message to the handler
                commandHandler.sendMessage(msg);
            }

        }catch (IOException e) {
            e.printStackTrace();
        }finally{
            if(socket != null)
                socket.close();
        }
    }
    socket.close()
}

/**
 * Close the listener
 */
public void shutDown(){
    this.stopped = true;

}

答案 1 :(得分:0)

显然有人在isClosed()测试和抛出异常的行之间关闭了它。

制作' socket'一个局部变量,然后没有其他人可以关闭它。

但是每次在循环中创建一个套接字首先完全没有意义。只需在线程的生命周期内使用相同的套接字。如果你从未在循环中关闭它,它可能不会抛出异常,你永远不需要测试它。