连接到公共 IP 地址的 Java 套接字
Posted
技术标签:
【中文标题】连接到公共 IP 地址的 Java 套接字【英文标题】:Java Socket connecting to a public ip-address 【发布时间】:2016-04-24 16:12:52 【问题描述】:我需要做一个服务器和连接到服务器的客户端。
问题:“服务器正常工作。客户端只能连接到本地主机,无法连接到互联网上的服务器。我希望客户端通过公共IP连接到服务器-服务器所在的地址。”
首先,我已确保端口已转发且可访问我已测试该端口,其次我已从服务器机器上完全禁用防火墙。
下面是我正在使用的测试代码:
服务器:没有什么特别简单的——如果客户端连接则终止,否则只是等待连接。
public class Server
public static void main(String args[])
try
ServerSocket srvr = new ServerSocket(52000);
srvr.accept();
catch(Exception e)
e.printStackTrace();
客户端:我已使用 no-ip.com 将服务器的 ip 掩码为“biogenserver2.noip.me”。 使用 .getCanonicalHostName(); 将返回 ip。
public class Client
public static void main(String args[])
try
String ip = Inet4Address.getByName("somets.noip.com").getCanonicalHostName();
InetSocketAddress sa = new InetSocketAddress(ip, 52000);
//Socket skt = new Socket("0.0.0.0", 52000); //local - this works fine.
Socket skt = new Socket();
skt.connect(sa);
catch(Exception e)
e.printStackTrace();
当我运行这个服务器连接正常,但客户端返回“连接超时”异常
任何帮助将不胜感激。谢谢。
【问题讨论】:
您是否尝试过保持连接一段时间?就像在服务器代码中做Socket s = srvr.accept();
然后Thread.sleep(100);
我怀疑连接没有足够的时间来完成握手。
是的,事实上,同样的问题仍然存在。通过 localhost 连接时,它连接的任何代码都没有问题。我也试过 skt.connect(sa, 50000);正如有人在下面建议的那样,但我仍然得到相同的结果。
只是为了清楚起见:您已经检查了端口是否通过 no-ip 返回的公共 IP 打开,并且当您运行那个小测试客户端时,服务器将无一例外地退出(在一台机器上是 不是服务器机器) - 对吗?
正确,但在不是服务器机器的机器上“不”。我在一台机器上同时运行。我开始认为,这可能是问题所在。
不客气!在同一台机器上超时仍然很奇怪......
【参考方案1】:
答案:
“只是为了清楚起见:您已经检查了端口是否通过 no-ip 返回的公共 IP 打开,并且当您运行那个小测试客户端(在不是服务器机器的机器上)时,服务器将毫无例外地退出) - 对吗?” – Fildor
TL:DR
不要在同一台机器和同一网络上运行客户端和服务器尝试通过您的公共 ip 连接到您的服务器然后连接到您自己的本地网络将导致客户端超时异常
我在同一台机器和同一网络上运行客户端和服务器。这导致了客户端超时异常。我尝试在不同的机器和不同的网络上运行客户端,我能够成功连接。
【讨论】:
【参考方案2】:您的应用程序使用什么版本的 IP 协议?在 linux 上,你可以通过netstat -tunap | grep 52000
来判断第一个字段是tcp
还是tcp6
。如果是后者,则可能存在 IPv6 连接问题,您可能希望通过将 -Djava.net.preferIPv4Stack=true
指定给 JVM 来更喜欢使用 IPv4 而不是 IPv6。
【讨论】:
Inet4Address 解决了这个问题,所以我不必这样做,我没有 ipv6,所以它应该获得 ipv4 - 这不是问题。以上是关于连接到公共 IP 地址的 Java 套接字的主要内容,如果未能解决你的问题,请参考以下文章