【问题标题】:Java Networking "Connection Refused: Connect"Java 网络“连接被拒绝:连接”
【发布时间】:2011-06-24 23:46:24
【问题描述】:

我一直在尝试运行一个简单的网络测试程序,但没有任何结果。

服务器:

import java.io.*;
import java.net.*;

public class ServerTest {
    public static void main(String[] args) {
    final int PORT_NUMBER = 44827;

    while(true) {
        try {
        //Listen on port
        ServerSocket serverSock = new ServerSocket(PORT_NUMBER);
        System.out.println("Listening...");

        //Get connection
        Socket clientSock = serverSock.accept();
        System.out.println("Connected client");

        //Get input
        BufferedReader br = new BufferedReader(new InputStreamReader(clientSock.getInputStream()));
        System.out.println(br.readLine());

        br.close();
        serverSock.close();
        clientSock.close();
        } catch(Exception e) {
        e.printStackTrace();
        }
    }
    }
}

客户:

import java.io.*;
import java.net.*;

public class ClientTest {
    public static void main(String[] args) throws IOException {
    final int PORT_NUMBER = 44827;
    final String HOSTNAME = "xx.xx.xx.xx";

    //Attempt to connect
    try {
        Socket sock = new Socket(HOSTNAME, PORT_NUMBER);
            PrintWriter out = new PrintWriter(sock.getOutputStream(), true);
        //Output
        out.println("Test");
        out.flush();

        out.close();
        sock.close();
    } catch(Exception e) {
        e.printStackTrace();
    }
    }
}

当我使用 127.0.0.1 或我的内部 IP 作为主机名时,程序运行良好。但是每当我切换到我的外部 IP 地址时,它都会引发 java.net.ConnectException: Connection refused: connect 错误。

我特意选择了这么一个不常见的端口,看看是不是这个问题,没有运气。 我可以使用 telnet 毫无问题地连接,但是当我尝试使用 canyouseeme.org 访问端口时,它告诉我连接超时。 我什至尝试禁用所有防火墙和防病毒软件,包括 Windows 默认防火墙和路由器防火墙,转发所有端口并启用 DMZ,但它仍然说连接超时。我使用 Comcast 作为我的 ISP,我怀疑他们会阻止这样一个随机端口。

当我使用数据包跟踪器时,它会显示我的计算机发送 SYN 并接收 RST/ACK 的 TCP 流量,因此它看起来像是一个标准的阻塞端口,并且没有其他可疑的数据包流量正在发生。

我不知道此时发生了什么;我几乎尝试了所有我知道的技巧。如果有人知道为什么端口可能被阻止,或者至少有某种方法可以使程序正常工作,那将非常有帮助。

【问题讨论】:

  • 我可能说的很明显,但你能telnet 到港口吗?这将有助于定位问题。另一个尝试的选择是只用一个监听netcat 替换服务器进程,看看你是否可以连接到它。
  • 也许有人可以给我一个简单的客户端/服务器程序,他们知道他们肯定可以在他们的计算机上运行。这将帮助我弄清楚问题是否仍然存在于端口转发和防火墙或我的代码上。

标签: java sockets networking port


【解决方案1】:

这些问题出现在以下情况:

  1. 客户端和服务器,其中一个或两个都不在网络中。

  2. 服务器未运行。

  3. 服务器正在运行但未监听端口,客户端正在尝试连接。

  4. 主机-端口组合不允许使用防火墙。

  5. 主机端口组合不正确。

  6. 连接字符串中的协议不正确。

如何解决问题:

  1. 首先你 ping 目标服务器。如果 ping 正常, 那么客户端和服务器都在网络中。

  2. 尝试使用 telnet 连接到服务器主机和端口。如果你是 能够连接它,那么您在客户端代码中犯了一些错误。

【讨论】:

  • 很好的答案。对我来说是 2.“服务器没有运行”。在您的客户端运行 main 之前,您必须确保您的服务器正在运行。
  • 所以对于 Windows,第二个选项帮助了我:telnet {external-ip} {port} 显示服务器无法访问。查看日志时,发现有人将空字符串作为 ip 的值。没有 ip = 没有连接。
【解决方案2】:

不管怎样,你的代码在我的系统上运行良好。

我不想这么说,但这听起来像是防火墙问题(我知道您已经检查了三次)或Comcast issue,这比您想象的更有可能。我会test your ISP

【讨论】:

    【解决方案3】:

    可能服务器套接字仅绑定到本地主机地址。您可以使用构造函数的 3 参数形式将其绑定到特定的 IP 地址。

    【讨论】:

    • 我试过这个:ServerSocket serverSock = new ServerSocket(PORT_NUMBER, 0, InetAddress.getByName("192.168.1.102")); 但没有骰子。还是不行。
    • 但是 192.168.1.102 不是外部地址。这是你的内部地址。我想我对您使用的地址感到困惑。
    • 我想知道我们是否走在正确的道路上。通常,服务器套接字无论如何都会绑定到所有可用的接口。我开始认为这是网络配置问题,而不是服务器套接字问题。
    【解决方案4】:

    我假设您正在使用路由器连接到 Internet。您应该进行端口转发以让公众访问您的内部网络。看看How do you get Java sockets working with public IPs?

    我还写了一篇关于端口转发的博文,你可能想看看 :) http://happycoders.wordpress.com/2010/10/03/how-to-setup-a-web-server-by-yourself/

    但我仍然无法通过公共 IP 访问它,现在正在处理它...

    【讨论】:

      【解决方案5】:

      我遇到了同样的问题,因为有时客户端在服务器之前启动,当他尝试建立连接时,它找不到正在运行的服务器。

      我的第一个(不是那么优雅的)解决方案是使用 sleep 方法让客户端停止一段时间:

      try {
         Thread.sleep(1000);
      } 
      catch (InterruptedException e) {
         e.printStackTrace();
      }
      

      我在客户端连接之前使用此代码,在您的示例中,就在Socket sock = new Socket(HOSTNAME, PORT_NUMBER);之前

      我的第二个解决方案是基于this 的答案。基本上我在客户端类中创建了一个方法,该方法尝试连接到服务器,如果连接失败,它会等待两秒钟再重试。 这是我的方法:

      private Socket createClientSocket(String clientName, int port){
      
          boolean scanning = true;
          Socket socket = null;
          int numberOfTry = 0;
      
          while (scanning && numberOfTry < 10){
              numberOfTry++;
              try {
                  socket = new Socket(clientName, port);
                  scanning = false;
              } catch (IOException e) {
                  try {
                      Thread.sleep(2000);
                  } catch (InterruptedException ie) {
                      ie.printStackTrace();
                  }
              }
      
          }
          return socket;
      }
      

      如你所见,这个方法尝试创建一个socket十次,然后socket返回一个空值,所以要小心检查结果。

      你的代码应该变成:

      Socket sock = createClientSocket(HOSTNAME, PORT_NUMBER);
      if(null == sock){ //log error... }
      

      这个解决方案帮助了我,我希望它也能帮助你。 ;-)

      【讨论】:

        猜你喜欢
        • 2011-06-28
        • 1970-01-01
        • 2014-10-10
        • 1970-01-01
        • 2017-08-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多