我有一个应用程序,其中我使用套接字来侦听来自服务器的消息,它有两个活动,每个活动都有自己的方法来处理消息。
当我从第一个开始第二个时,我关闭该活动的套接字监听器并在第二个活动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
中从之前遗留下来代码的版本。无论如何,谢谢你的所有答案,如果我浪费了你的时间,那就很抱歉
答案 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'一个局部变量,然后没有其他人可以关闭它。
但是每次在循环中创建一个套接字首先完全没有意义。只需在线程的生命周期内使用相同的套接字。如果你从未在循环中关闭它,它可能不会抛出异常,你永远不需要测试它。