地址已在使用 java,java.net.BindException:绑定失败:EADDRINUSE(地址已在使用)

I have a service, which starts Thread to perform some operations on socket. The code looks like:

public class ServerRunnable implements Runnable {

@Override

public void run() {

ServerSocket serverSocket = null;

try {

serverSocket = new ServerSocket();

serverSocket.setReuseAddress(true);

serverSocket.bind(new InetSocketAddress(ProtocolConstants.USB_SERVER_PORT));

while (true) {

Socket client = serverSocket.accept();

// some code

} catch (Exception e) {

Log.e("Exception while listening on socket.", e);

} finally {

if (serverSocket != null) {

try {

serverSocket.close();

} catch (IOException e) {

Log.e(e);

}

}

}

When I start service first time, everything is ok, but then I have to stop it using stopService method. When I start it one more time it returns following exception:

java.net.BindException: bind failed: EADDRINUSE (Address already in use)

In addition I added ServerSocket closing in onDestroy method of service but it did not help.

The setReuseAddress is performed before bind, so why it is not working?

解决方案

As far as I can guess it gets stuck on serverSocket.accept(), waiting for a connection to come in. Hence the Runnable does never finish even after closing the app. Calling the app again gives you this error (because the port is still blocked by the Runnable that was created before that). There are multiple ways of handling this:

You can call and stop your Runnable like this:

ThreadPoolExecutor threadPoolExecutor = Executors.newSingleThreadExecutor();

Runnable longRunningTask = new Runnable();

Future longRunningTaskFuture = threadPoolExecutor.submit(longRunningTask);

longRunningTaskFuture.cancel(true); //this might not trigger right away

You can stop the serverSocket.accept() by calling serversocket.close() (which will throw a SocketException that needs to be handled)

I solved this (might not be the correct way to handle this) by sending data (a string) to my serverSocket from the onClose() method in my Activity:

Socket socket = new Socket();

socket.setReuseAddress(true);

socket.connect((new InetSocketAddress(YOURSETTINGS, HERE);

OutputStream os = socket.getOutputStream();

ObjectOutputStream oos = new ObjectOutputStream(os);

oos.writeObject(new String("TIMEOUT"));

oos.close();

os.close();

socket.close();

You can optionally catch this in your server like this:

ObjectInputStream objectInputStream = new objectInputStream(serverSocket.getInputStream());

Object object = objectInputStream.readObject();

if (object.getClass().equals(String.class) && ((String) object).equals("TIMEOUT"))

{

//Here you can do something with the Runnable before it is gone

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值