Java 套接字,绑定到本地端口。

10

我正在尝试将客户端套接字绑定到任何特定的本地端口,在这段代码中,我使用了20000。

像下面这样的正常连接运行良好。但是不允许我选择本地端口。

hostSocket = new Socket(host,80);

于是我尝试了这个:

hostSocket = new Socket(host, 80, InetAddress.getLocalHost(), 20000);

和这个:

hostSocket = new Socket();
hostSocket.bind(new InetSocketAddress("localhost", 20000));
hostSocket.connect(new InetSocketAddress(host,80));

但是它们都使我感到异常...在第二种情况下,异常发生在连接调用上。我不太确定自己缺少什么,希望能得到一些指示。

java.net.SocketException: Invalid argument or cannot assign requested address
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:327)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:193)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:180)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:384)
at java.net.Socket.connect(Socket.java:546)
at java.net.Socket.connect(Socket.java:495)
at com.mb.proxy.netflix.NetflixPrefetchingAgent.connect(NetflixPrefetchingAgent.java:98)
at com.mb.proxy.netflix.NetflixPrefetchingAgent.run(NetflixPrefetchingAgent.java:164)
at java.lang.Thread.run(Thread.java:679)
Exception in thread "Thread-19" java.lang.NullPointerException
at com.mb.proxy.netflix.NetflixPrefetchingAgent.prefetchChunk(NetflixPrefetchingAgent.java:272)
at com.mb.proxy.netflix.NetflixPrefetchingAgent.run(NetflixPrefetchingAgent.java:176)
at java.lang.Thread.run(Thread.java:679)

1
你为什么关心出站本地端口是什么? - Brian Roach
1
@Brian Roach 我正在为研究目的限制特定端口的带宽。需要知道我的应用程序的某些部分使用哪些端口才能使其正常工作。 - user2041602
2
我认为你必须绑定到实际的出站IP地址(而不是将解析为127.0.0.1的本地主机)- 不过我需要测试一下。 - Brian Roach
2个回答

36

你需要绑定到你机器的外部(出站)IP地址,而不是本地地址 (127.0.0.1)。

以下内容在我的计算机上可以正常工作:

Socket s = new Socket();
s.bind(new InetSocketAddress("172.16.1.102", 5000));
s.connect(new InetSocketAddress("google.com", 80));

这里的 172.16.1.102 是通过DHCP从我的路由器分配给此计算机的NAT'd私有网络地址。


3
谢谢Brian,我刚测试了一下,它可以工作。很抱歉我没有足够的声望来点赞你的回答。 - user2041602
你好@BrianRoach,我们不应该将绑定和连接到同一个InetSocketAddress,比如服务器?这就像我们需要绑定到一个socketaddress并连接到另一个?我有点困惑。你能否请澄清一下这个问题? - KK_07k11A0585

4

Brian的答案准确地指出了问题所在。

然而,您不需要出站接口的IP地址,因为您可以简单地指定“任何地址”的0.0.0.0。正确的出站接口将自动选择。这很像当您在没有绑定的情况下连接时。

此外,最简便的方法是省略该参数,直接指定0.0.0.0作为地址。

因此:

hostSocket = new Socket();
hostSocket.bind(new InetSocketAddress(20000));
hostSocket.connect(new InetSocketAddress(host, 80));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接