【问题标题】:Java(Android): create ServerSocket on LocalPort used for another SocketJava(Android):在用于另一个 Socket 的 LocalPort 上创建 ServerSocket
【发布时间】:2014-08-21 13:52:17
【问题描述】:

我有点难过,可能是因为我不知道如何正确搜索(我尝试了许多不同的关键字)。无论如何,我正在尝试 TCP 打孔的变体(使用集合服务器)。我已经创建了一个到服务器的 TCP 套接字并关闭它而不抛出任何异常。但是当我尝试在原始套接字的本地端口上创建一个 ServerSocket 时,它会因 IOException 而失败。

private static int LOCALPORT = 0;
private static String TARGETIP = "88.888.88.888";
private static int TARGETPORT = 8888;
try{
    InetAddress serverAddr = InetAddress.getByName(TARGETIP);
    socket = new Socket(serverAddr, TARGETPORT);
    LOCALPORT = socket.getLocalPort();
    socket.close();
    ServerSocket sSocket = new ServerSocket(LOCALPORT);
    Socket skt = sSocket.accept();
}
catch (IOException e){
}

我无法理解为什么我不能关闭套接字并在同一端口上打开服务器套接字。

更新:来自 logcat

java.net.BindException: bind failed: EADDRINUSE (Address already in use)
Caused by: libcore.io.ErrnoException: bind failed: EADDRINUSE (Address already in use)

【问题讨论】:

  • 因什么 IOException 而失败?
  • 请告诉我如何找出给出的 IOException,我很乐意在这里提供。我不是一个很有经验的程序员。我只知道上面的 catch 执行了,因此它是一个 IOException。
  • 在 catch 块中添加一个打印 e.getMessage() 的日志行。还要加一行e.printStackTrace(); 然后在logcat里看一下,发到这里。

标签: java android sockets tcp hole-punching


【解决方案1】:

我认为你的socket = new Socket(serverAddr, TARGETPORT); 会抛出IOException。因为您使用的 IP 地址无效。否则这段代码应该可以正常工作。

【讨论】:

  • 感谢您的回答,但是创建套接字没有问题。我的问题是 ServerSocket 创建。我在那里放了一个虚拟 IP,所以我不会在此处列出我的实际公共 IP :)
  • @user2981258 除非您在上面回答我的问题,否则您的问题可能会因信息不足而被关闭。
  • @EJP 不用客气,我想知道如何回答你的问题(无济于事),但可以立即回答。
【解决方案2】:

你会得到一个IOException 试图监听刚刚检索到的本地端口:

 bind failed: EADDRINUSE (Address already in use)

我认为应该是这样的:

 port already in use

我不知道为什么那个端口没有被释放。有没有解绑的可能?

【讨论】:

  • 你是对的! :) 关于如何解除套接字绑定的任何想法?
【解决方案3】:

我相信我已经解决了我自己的问题,这要归功于 greenapps 和一些额外的在线搜索。您需要将其设置为重用,而不是关闭原始套接字!好简单,哇。

private static int LOCALPORT = 0;
private static String TARGETIP = "88.888.88.888";
private static int TARGETPORT = 8888;
try{
    InetAddress serverAddr = InetAddress.getByName(TARGETIP);
    socket = new Socket(serverAddr, TARGETPORT);
    LOCALPORT = socket.getLocalPort();
    //socket.close();
    socket.setReuseAddress(true);
    ServerSocket sSocket = new ServerSocket(LOCALPORT);
    Socket skt = sSocket.accept();
    sSocket.close();
}
catch (IOException e){
    e.getMessage();
    e.printStackTrace();
}

【讨论】:

  • 没有。这并不能解决任何问题。当你调用 setReuseAddress() 时,'socket' 已经被绑定,因此什么都不做。
  • 嘿伙计,您尝试运行代码了吗?如果你这样做了,你会看到它不再抛出异常,我可以创建 ServerSocket。请查看您还发布的链接(尽管您在那里也没有提供任何有用的信息),其中包含答案:oracle forum。感谢您在不知道您在说什么的情况下投反对票!
猜你喜欢
  • 2019-09-27
  • 2014-12-21
  • 1970-01-01
  • 2012-10-30
  • 2019-09-24
  • 2013-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多