Java.net.ConnectException: 连接被拒绝

243

我正在尝试实现TCP连接,服务器方面一切正常,但是当我运行客户端程序(来自客户端计算机)时,我收到以下错误:

java.net.ConnectException: Connection refused
        at java.net.PlainSocketImpl.socketConnect(Native Method)
        at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:351)
        at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:213)
        at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:200)
        at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:432)
        at java.net.Socket.connect(Socket.java:529)
        at java.net.Socket.connect(Socket.java:478)
        at java.net.Socket.<init>(Socket.java:375)
        at java.net.Socket.<init>(Socket.java:189)
        at TCPClient.main(TCPClient.java:13)

我尝试更改套接字号码以防止被占用,但是没有成功,有谁知道是什么原因导致了这个错误以及如何解决它。

服务器代码:

//TCPServer.java

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

class TCPServer {
    public static void main(String argv[]) throws Exception {
        String fromclient;
        String toclient;

        ServerSocket Server = new ServerSocket(5000);

        System.out.println("TCPServer Waiting for client on port 5000");

        while (true) {
            Socket connected = Server.accept();
            System.out.println(" THE CLIENT" + " " + connected.getInetAddress()
                    + ":" + connected.getPort() + " IS CONNECTED ");

            BufferedReader inFromUser = new BufferedReader(
                    new InputStreamReader(System.in));

            BufferedReader inFromClient = new BufferedReader(
                    new InputStreamReader(connected.getInputStream()));

            PrintWriter outToClient = new PrintWriter(
                    connected.getOutputStream(), true);

            while (true) {

                System.out.println("SEND(Type Q or q to Quit):");
                toclient = inFromUser.readLine();

                if (toclient.equals("q") || toclient.equals("Q")) {
                    outToClient.println(toclient);
                    connected.close();
                    break;
                } else {
                    outToClient.println(toclient);
                }

                fromclient = inFromClient.readLine();

                if (fromclient.equals("q") || fromclient.equals("Q")) {
                    connected.close();
                    break;
                } else {
                    System.out.println("RECIEVED:" + fromclient);
                }

            }

        }
    }
}

客户端代码:

//TCPClient.java

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

class TCPClient {
    public static void main(String argv[]) throws Exception {
        String FromServer;
        String ToServer;

        Socket clientSocket = new Socket("localhost", 5000);

        BufferedReader inFromUser = new BufferedReader(new InputStreamReader(
                System.in));

        PrintWriter outToServer = new PrintWriter(
                clientSocket.getOutputStream(), true);

        BufferedReader inFromServer = new BufferedReader(new InputStreamReader(
                clientSocket.getInputStream()));

        while (true) {

            FromServer = inFromServer.readLine();

            if (FromServer.equals("q") || FromServer.equals("Q")) {
                clientSocket.close();
                break;
            } else {
                System.out.println("RECIEVED:" + FromServer);
                System.out.println("SEND(Type Q or q to Quit):");

                ToServer = inFromUser.readLine();

                if (ToServer.equals("Q") || ToServer.equals("q")) {
                    outToServer.println(ToServer);
                    clientSocket.close();
                    break;
                } else {
                    outToServer.println(ToServer);
                }
            }
        }
    }
}

我关闭了客户端和服务器上的防火墙,但问题仍然存在。 - Samantha Catania
2
服务器正在监听哪个接口。如果您只在本地主机上进行监听,则无法进行远程连接。 - Thorbjørn Ravn Andersen
我试图在使用本地主机时进行远程连接,真是自讨苦吃。这是我第一次尝试使用TCP >.< 如何使其在远程工作? - Samantha Catania
请记住,您可能还有一些“裸机”硬件防火墙在中间...如果客户端和服务器在同一台计算机上,它是否有效? - home
Server Fault有一个关于“连接被拒绝”(Connection Refused)的规范问题,链接为http://serverfault.com/questions/725262/what-causes-the-connection-refused-message。 - Raedwald
显示剩余3条评论
20个回答

405

此异常表示您尝试连接的IP/端口上没有服务正在监听:

  • 您正在尝试连接错误的IP/主机或端口。
  • 您还没有启动您的服务器。
  • 您的服务器没有在监听连接。
  • 在Windows服务器上,监听队列已满。

只是为了明确这一点 - “Java核心非常好”。唯一的问题是我们忽视了问题..(服务器状态、IP地址、端口、互联网连接 - 必须在同一路由器上才能使用本地IP等) - Vinay Bhargav
1
Collin,你说的“服务器不等待接受连接”是什么意思?人们总是滥用这个词汇,仿佛它有些含义。 - user207421
我之前写过这个,但我认为我是想用另一种方式来说你还没有启动你的服务器。 - Collin Price
在我的情况下,我有四个Gennymotion模拟器正在运行,我试图在Galaxy Tab上加载应用程序,但是我一直收到这个错误。在从伙伴网站上阅读了很多内容后,我关闭了所有模拟器和Eclipse,杀死了任务管理器中的ADP,然后重新启动了Eclipse,一切都开始正常工作了。我认为当您运行多个模拟器并尝试连接设备时,ADB会出现问题。这是我的两分钱... :) - Vincy
如果你正在使用Spring Boot版本低于1.4,请检查是否已激活WebIntegrationTest...这对我起到了作用。 - Jan Galinski
显示剩余4条评论

48
我会检查:
  • 您正在尝试连接的主机名和端口号
  • 服务器端是否已成功开始监听
  • 没有防火墙阻止连接

最简单的起点可能是尝试使用telnet或Putty在客户端机器上手动连接。如果成功,则问题出现在您的客户端代码中。如果失败,您需要找出失败原因。可以使用Wireshark来帮助您解决此问题。


有时候我会遇到这个异常。这种情况发生在特定的时间段内。它会立即抛出此异常,然后一切都变得正常了。我的服务器上有一个防火墙。但是我已经添加了一个入站规则来允许端口8080上的传入连接。这个规则有时会被忽略吗? - Ashwin
@Ashwin:实际上很难说——你需要确定数据到达的确切位置。查看防火墙日志等信息。 - Jon Skeet
@JonSkeet 如果我们遇到这个错误,应该如何配置防火墙? - Nikhil Pareek
1
@Nikhil:我不够资格回答这个问题,但我猜想任何有资格的人都需要更多的信息才能帮助你。(首先,我们并不知道你使用的是哪种防火墙......) - Jon Skeet

8

我曾遇到同样的问题,但是先运行服务器再运行客户端可以解决这个问题。


6
当然,在启动客户端之前必须先运行服务器。如果首先运行客户端并尝试连接服务器,则在启动服务器时您将无法连接到任何东西。 - user3308043
6
@user3308043 是的,这很明显,但对于一些新手程序员(比如我三年前),它并不是太明显,所以我只是想与那些像我一样无知的同行分享一下。 - Dao Lam
谢谢,这也帮了我很多。测试连接成功了,但无法显示任何表格数据。 - Damien Christophe

8

你需要将客户端套接字连接到远程的ServerSocket。不要使用:

Socket clientSocket = new Socket("localhost", 5000);

而要使用:

Socket clientSocket = new Socket(serverName, 5000);

客户端必须连接到 serverName,该名称或IP地址应与实例化ServerSocket所在的计算机的名称或IP地址匹配(名称必须从客户端机器上可访问)。顺便提一下:重要的不是名称,而是IP地址...


我想她正在同一台机器上运行这两个程序进行测试,这就是为什么可以使用本地主机的原因。 - user545199
@Aaron:她说如果客户端和服务器在同一台机器上运行,它可以正常工作(您可以在另一个评论中找到答案)。 - home
以上行将套接字绑定到本地主机。不,它没有,它将其绑定到INADDR_ANY。这允许通过任何NIC接受连接。OP正在做的已经正确了。答案完全错误。向下投票。 - user207421
@EJP:关于ServerSocket,你是正确的,我修改了答案。不过clientSocket仍然尝试连接到localhost - home
@home 你需要删除关于绑定地址的短语。 - user207421
@home bind() 将套接字绑定到本地 NIC 和端口。connect() 连接到远程 IP:port。它们是完全不同的操作。 - user207421

8
我想要补充一点关于以上答案的经验:

"I在我的本地服务器上托管,并试图通过指定正确的URL(如http:// localhost / my_api / login.php )从android模拟器连接到它。我遇到了连接被拒绝的错误"

请注意 - 当我只是在PC上使用相同的URL(http:// localhost / my_api / login.php )浏览器时,我得到了正确的响应

所以,在我的情况下,问题出在术语“localhost”上,我用服务器的 IP 替换了它(因为你的服务器托管在你的机器上),这使得它可以从我在同一台PC上的模拟器中访问。


要获取本地计算机的IP,请在cmd上使用 ipconfig 命令,您将获得类似192.68.xx.yy的IPv4地址 看,那就是您的服务器托管所在的计算机的IP地址。 然后使用它而不是localhost

http:// 192.168.72.66 / my_api / login.php
请注意 - 您将无法从此计算机外部的任何节点访问此私有IP。(如果需要,可以使用Ngnix进行访问)


4

我曾经遇到过与称为Vernemq的Mqtt代理相同的问题,但是通过添加以下内容解决了问题。

  1. $ sudo vmq-admin listener show

以显示允许的IP和端口列表对于vernemq.

  1. $ sudo vmq-admin listener start port=1885 -a 0.0.0.0 --mountpoint /appname --nr_of_acceptors=10 --max_connections=20000

添加任何IP和您的新端口。现在您应该能够连接而没有任何问题。

希望它能解决您的问题。 enter image description here


1
这个救了我的命,但由于vernemq不能通过apt-get安装,有些人将需要这个链接:https://vernemq.com/docs/installation/debian_and_ubuntu.html - 3xCh1_23

1

我更改了我的DNS网络,问题得到了解决。


1
希望我的经验对某些人有用。我遇到了与相同异常堆栈跟踪相关的问题,但我无法理解问题所在。我尝试连接的数据库服务器正在运行,并且端口已打开并接受连接。
问题出在网络连接上。我使用的网络连接未被允许连接到相应的服务器。当我更改连接详细信息时,问题得到解决。

1
在我的情况下,我给套接字命名为服务器的名称(在我的情况下是“raspberrypi”),而不是使用IPv4地址,或者更确切地说,IPv6无法使用(该名称解析为IPv6)。

1
我之所以出现这个错误,是因为我在一个for循环中关闭了ServerSocket,该循环尝试在其中接受多个客户端(但我没有接受完所有客户端)。
因此,请注意在何处关闭您的套接字。

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