我无法使用外部IP与Java.Socket连接我的电脑

时间:2014-08-23 17:04:12

标签: java sockets ip external

我使用Java.Sockets创建了一个简单的套接字应用程序。 我在同一台电脑上运行客户端和服务器,它连接了调制解调器和其他一些电脑。 客户端可以使用本地ip连接到服务器。但是当它尝试连接外部IP时,它会失败。

这里是服务器代码:

    int portno=Integer.parseInt(args[0]);
    ServerSocket ssock = new ServerSocket(portno);


    while(true){

        Socket csock = ssock.accept();

        PrintWriter out = new PrintWriter(csock.getOutputStream(), true);
        BufferedReader in = new BufferedReader( new InputStreamReader(csock.getInputStream()));

        String buffer = in.readLine();

        System.out.println(buffer);

        csock.close();

    }

客户代码:

    public static void main(String args[]) throws Exception{
    String ip="My External IP";
    int port=Integer.parseInt(args[0]);
    Socket sock = new Socket(ip,port);
    PrintWriter out = new PrintWriter(sock.getOutputStream(), true);
    BufferedReader in = new BufferedReader( new InputStreamReader(sock.getInputStream()) );
    BufferedReader stdin =  new BufferedReader( new InputStreamReader(System.in) );

    String buffer=stdin.readLine();

    out.println(buffer);

    sock.close();

}

1 个答案:

答案 0 :(得分:0)

这是套接字变得复杂的地方。它们在封闭的网络上工作正常,但一旦它们被网络地址转换器(路由器)分开,你需要寻找其他方法。

路由器会阻止所有传入的流量/连接,除非路由器是专门的端口转发或传入流量是它自己的请求(例如获取网页)的答案

为了让您的路由器接受连接,您需要对其进行配置。 另一种方法是使用一种名为"打孔的方法"。这是Skype等软件使用的技术。该技术各不相同,并且在很大程度上是非官方的,但其背后的一般概念是:

  • 计算机A想要访问计算机B
  • 计算机A和计算机B不知道彼此的位置,但都知道官方超级节点。超级节点包含所有连接用户的列表。
  • 计算机A和计算机B从超级节点检索彼此的位置后。
  • 计算机A向计算机B发送请求,在其路由器中创建一个洞,等待响应。
  • 计算机B没有得到请求,它自己的路由器会阻止请求,但它知道计算机A希望通过与超级节点通信来访问它。
  • 计算机B通过路由器中的漏洞将新的数据包发送回计算机A,使其认为它已收到它的响应。计算机B现在有一个孔,并且连接被颠倒以使其成为双向的。两台计算机现已连接。

打孔是连接客户端的唯一方法之一,虽然它确实需要第三个超级节点"。打孔是一种非官方的解决方案,不幸的是有缺陷。并非所有路由器都支持打孔,这意味着没有具体的方法来连接客户端。还有另一种选择,使用STUN或ICE服务器。 网上的文档很少,但我知道它可以作为连接两个客户端的中继。我自己发布了一个关于STUN服务器和客户端的问题。

安全性和连接性之间存在长期争斗,在它被解决并且p2p连接标准化之前,您将不得不寻找新的和创造性的方法来使其发挥作用。

我希望这有点帮助。

UDP穿孔:http://en.wikipedia.org/wiki/UDP_hole_punching

STUN:http://en.wikipedia.org/wiki/STUN