无法绑定TCP公网端口问题排查与解决咨询
问题描述
我需要在开发机器(MacBook)与另一台服务器之间建立TCP连接,二者处于同一路由器下、共用公网IP。
使用路由器公网IP尝试建立连接时失败,但配置好路由器端口转发后,用Python TCP脚本测试公网IP可正常工作,使用私有IP也能顺利建立连接。
代码片段
new InetSocketAddress(serverIpAddress, serverTcpPort)
抛出异常
Bind failed for TCP channel on endpoint [/<My Public Ip>:8132] java.net.BindException: Can't assign requested address at java.base/sun.nio.ch.Net.bind0(Native Method) at java.base/sun.nio.ch.Net.bind(Net.java:459) at java.base/sun.nio.ch.Net.bind(Net.java:448) at java.base/sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:227) at java.base/sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:80) at akka.io.TcpListener.liftedTree1$1(TcpListener.scala:59) at akka.io.TcpListener.<init>(TcpListener.scala:56) at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490) at akka.util.Reflect$.instantiate(Reflect.scala:68) at akka.actor.ArgsReflectConstructor.produce(IndirectActorProducer.scala:101) at akka.actor.Props.newActor(Props.scala:212) at akka.actor.ActorCell.newActor(ActorCell.scala:650) at akka.actor.ActorCell.create(ActorCell.scala:676) at akka.actor.ActorCell.invokeAll$1(ActorCell.scala:549) at akka.actor.ActorCell.systemInvoke(ActorCell.scala:571) at akka.dispatch.Mailbox.processAllSystemMessages(Mailbox.scala:293) at akka.dispatch.Mailbox.run(Mailbox.scala:228) at akka.dispatch.Mailbox.exec(Mailbox.scala:241) at akka.dispatch.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260) at akka.dispatch.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339) at akka.dispatch.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979) at akka.dispatch.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
疑问
- 如何解决该问题?
- 为何私有IP可行但公网IP不行?
- 输入错误私有IP时连接也失败,TCP套接字服务器绑定端口时会检查客户端可用性吗?
解决方案与解释
1. 问题解决方法
不要绑定到公网IP,而是绑定到0.0.0.0或者服务器的私有IP:
- 绑定
0.0.0.0时,服务器会监听所有可用的网络接口,既能接收同局域网内私有IP的请求,也能接收路由器端口转发过来的公网流量; - 明确服务器私有IP的话,直接绑定该IP也可正常工作。
修改代码示例:
new InetSocketAddress("0.0.0.0", serverTcpPort)
2. 私有IP可行但公网IP不行的原因
公网IP是绑定在路由器上的,并非服务器网卡实际配置的IP地址。
- 绑定操作需要对应IP存在于本地网卡上,系统检测到服务器没有公网IP,就会抛出
BindException; - 私有IP是服务器网卡实际分配的地址,所以绑定操作能顺利完成;
- Python脚本能通过公网IP连接,是因为路由器的端口转发把公网请求映射到了服务器私有IP,这和服务器绑定公网IP是完全独立的两个流程。
3. 服务器绑定端口时是否检查客户端可用性?
不会。服务器绑定端口只是在本地网卡开启监听,这个过程和客户端没有任何关联。
输入错误私有IP时连接失败,是客户端在尝试连接阶段找不到目标IP对应的服务,属于客户端连接环节的错误,和服务器绑定端口的操作无关。
内容的提问来源于stack exchange,提问作者MohanaSundaram J
相关产品推荐
相关产品推荐

