Java ServerSocket和Android LocalServerSocket
我已经实现了我自己的android服务,如下所示Java ServerSocket和Android LocalServerSocket,java,android,sockets,serversocket,Java,Android,Sockets,Serversocket,我已经实现了我自己的android服务,如下所示 public class MyService extends Service { private static final String TAG = "MyService"; private Server mServer; private LocalServerSocket server; @Override public IBinder onBind(Intent intent) {
public class MyService extends Service {
private static final String TAG = "MyService";
private Server mServer;
private LocalServerSocket server;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
Log.d(TAG, "onCreate");
mServer = new Server();
mServer.start();
}
@Override
public void onDestroy() {
Log.d(TAG, "onDestroy");
if(server != null){
try {
server.close();
} catch (IOException e) {
Log.d(TAG, "exception in server close");
e.printStackTrace();
}
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "onStart");
return START_STICKY;
}
class Server extends Thread {
@Override
public void run() {
try {
server = new LocalServerSocket("my.socket");
while (true) {
LocalSocket receiver;
try{
receiver = server.accept();
}catch(SocketException e){
Log.d(TAG, "SocketException");
break;
}
catch(IOException e){
Log.d(TAG, "IOException");
break;
}
if (receiver != null) {
Log.d(TAG, "Got Data in receiver");
}
receiver.close();
}
} catch (IOException e) {
Log.d(TAG, "one more");
e.printStackTrace();
}
}
}
}
我面临的问题是,如果我的LocalServerSocket在accept()中阻塞,那么在OnDestroy()中调用server.close()将不会抛出SocketException。因此,下次启动该服务时,我会得到“地址已在使用异常”。如果我使用java.net.Socket而不是LocalServerSocket,那么我将获得所需的行为。我想知道为什么LocalServerSocket的行为不同于Java套接字。在我的例子中,如何走出while循环。从您发布的代码来看,您的
LocalServerSocket服务器将永远保持null
,并且ondestry()
不会关闭它。另外,关闭套接字通常不会引发IOException,但是如果套接字同时关闭,accept()
会引发IOException 我也遇到了同样的问题,并通过这种方式“解决”了它。thread run()方法正在检查“!isInterrupted()”。我添加到侦听器线程中的方法“stopSocketServer()”将线程标记为interrupt(),然后向自身发出连接请求以触发accept()方法
你是说我应该创建另一个线程来关闭套接字?我试过了,但问题仍然存在。只要我在等待accept(),我就无法再次使用该地址!我的代码有什么改进吗?
/**
* Executed if thread is started.
*/
public void run() {
try {
// leave while loop if thread is marked for interrupt.
while (!isInterrupted()) {
LocalSocket clientSocket = serverSocket.accept();
if (!isInterrupted()) {
threadPool.execute(new ClientProcessor(clientSocket));
}
}
} catch (IOException e) {
if (!isInterrupted()) {
Log.e(TAG, "socket listener terminated", e);
}
} finally {
try {
if (serverSocket != null) {
serverSocket.close();
}
if (threadPool != null) {
threadPool.shutdownNow();
}
Log.i(TAG, "socket listener stopped");
} catch (IOException e) {
}
}
}
public void stopSocketServer() {
if (serverSocket != null) {
try {
// mark thread as interrupted
interrupt();
// now send connect request to myself to trigger leaving accept()
LocalSocket ls = new LocalSocket();
ls.connect(serverSocket.getLocalSocketAddress());
ls.close();
} catch (IOException e) {
Log.e(TAG, "stopSocketServer failed", e);
}
}
}