【问题标题】:a bizarre Connection refused: connect error in Java client一个奇怪的连接被拒绝:Java 客户端中的连接错误
【发布时间】:2013-02-25 01:19:00
【问题描述】:

我遇到了以下错误:

java.net.ConnectException: Connection refused: connect

我将在下面展示一些代码,但首先是描述,因为它让我感到困惑。我编写了一个非常基本的聊天程序,它可以充当服务器或客户端,具体取决于您按下的初始按钮(主机或连接)。与朋友一起在本地主机和互​​联网上进行了测试,按预期完美运行。我已经开始编写第二个软件并使用几乎相同的代码,但是有更多类,当我尝试连接到同一程序的主机时出现此错误。因此,prog A 可以很好地连接到 prog A,但 B 无法连接到 B。人们可能会认为防火墙存在问题,但这里的情节扭曲:B 可以连接到 A,A 可以再次完美地连接到 B。但是 B 无法连接到自身的另一个副本。我使用 TCP 的官方 oracle 教程并在称为 A 的聊天程序上完美运行。根据按钮的按下,A 将运行其主要类的方法之一(启动服务器或客户端)。另一方面,B 将创建一个类的新对象,或者是 Host

public class Host
{
static ServerSocket serverSocket = null;
static Socket clientSocket = null;
static PrintWriter out = null;
static BufferedReader in = null;
static String inputLine;
public Host() throws IOException
    {
    serverSocket = new ServerSocket(4444);
    System.out.println("Server created, waiting for guest.");
    clientSocket = serverSocket.accept();
    System.out.println("Guest connected.");
    out = new PrintWriter(clientSocket.getOutputStream(), true);
    in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
    while ((inputLine = in.readLine()) != null)
        {
        //if (inputLine.equals("q")) {break;}
        System.out.println("Message recieved:" + inputLine);
        }
    }
}

或客人

public class Guest
{
static Socket socket = null;
static PrintWriter out;
static BufferedReader in = null;
static String inputLine;
public Guest() throws IOException
    {
    System.out.println("Connecting to host");
    try
        {socket = new Socket("localhost", 4444);
         out = new PrintWriter(socket.getOutputStream(), true);
        in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        }
    catch (UnknownHostException err) {System.out.println("unknown host"); System.exit(3);}
    catch (IOException err) {System.out.println(err); /*System.exit(4);*/}
    System.out.println("Connected to host");

    while ((inputLine = in.readLine()) != null)
        {
        //if (inputLine.equals("q")) {break;}
        System.out.println("Message recieved:" + inputLine);
        }
    }
}

我有正确的导入,我只是没有将它们粘贴到这里。两个程序都尝试连接到本地主机,只有 A 可以工作,而另一个不能。同样,创建一个访客,我可以连接到聊天程序的服务器。聊天程序客户端可以连接到此服务器。但是这个客户端无法连接到这个服务器。

有没有人经历过类似的事情?有没有明显的解决方案,我错过了什么?我真的一无所知,我从字面上复制/粘贴了服务器/客户端代码。

编辑:堆栈跟踪。

java.net.ConnectException: Connection refused: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
java.net.ConnectException: Connection refused: connect
at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:69)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:339)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:200)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:182)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:157)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:391)
at java.net.Socket.connect(Socket.java:579)
at java.net.Socket.connect(Socket.java:528)
at java.net.Socket.<init>(Socket.java:425)
at java.net.Socket.<init>(Socket.java:208)
at mainPack.Guest.<init>(Guest.java:21)
at mainPack.GameStarter.grandMain(GameStarter.java:101)
at mainPack.GameStarter.<init>(GameStarter.java:27)
at mainPack.GameStarter.main(GameStarter.java:34)

【问题讨论】:

  • 我不明白。 “一个聊天程序客户端可以连接到这个服务器”和“但是这个客户端不能连接到这个服务器”有什么区别?
  • 两个不同的程序,它们旨在充当另一个自身实例的服务器或客户端。程序 A 可以连接到程序 A 的另一个实例。B 不能连接到另一个 B。B 可以连接到 A,A 可以连接到 B,这本来就不应该这样使用,但它们可以建立连接。

标签: java connection client


【解决方案1】:

在您的主机中,您只接受一个连接,然后服务器停止侦听。如果有什么东西阻碍了这个连接,那么其他任何东西都无法连接到主机。接受的连接应立即委托给另一个线程进行处理,以便主机可以循环并再次侦听服务器套接字。请参阅Socket tutorial 中的"Supporting Multiple Clients"

【讨论】:

  • 这个主机应该只接受一个连接。它从不接受,只有当我连接到聊天程序时,如前所述,它可以完美地使用几乎相同的代码。
  • 一切看起来都很简单,我可以复制/粘贴您的代码,添加主要方法,并运行主机和来宾并获得预期的结果。它必须是您未显示的某些代码中的某些内容。我的下一个猜测是,当您启动“程序 B”客户端时,它会在启动客户端之前停止“程序 B”服务器,但我在这里只是在黑暗中拍摄。
  • 服务器似乎在等待连接,即使在尝试连接后也是如此。我的主要方法永远不会结束,因为 Host 一直在尝试接受。我正在查看其他代码,但我不知道是什么原因造成的。该程序首先创建两个按钮。它们具有将名为“ServerOrGuest”的变量设置为 1 或 2 的操作侦听器。while 无限循环(从睡眠开始)查看 ServerOrGuest 以查看它是否应该创建主机或访客。所有这一切都与前面的程序相同,只是它创建了新的对象,它调用了方法。
  • 我唯一能建议的另一件事是将问题简化为SSCCE 并发布,以便我们可以看到它的实际效果。
【解决方案2】:

Guest 中的变量中删除您的static 声明。 Host 也一样(不过如果你只有一个主机应该没问题)。

更新

例如伪代码

create server socket
while true (or quit received) {
    accept connection
    spawn thread to handle communication
}

【讨论】:

  • 照做了,没有任何改变。
  • 好的。好吧,它绝对不适用于static。事情会很糟糕。
  • 您应该生成一个线程来处理通信,并让主机通过accept() 附加另一个客户端。接受应该在一个循环中。
  • 哦,不。请不要静电!这是您不需要的另一个复杂功能。
  • xagyg 是正确的。查看众多网络(真实世界)示例代码。有一个众所周知的服务器套接字,但在每次“accept()”调用时,都需要使用自己的套接字句柄创建一个新线程来“分叉”该通信。最终发生的情况是,主端口上的侦听器只是一个代理,用于在客户端和新服务器线程之间分叉成对通信,每次使用新创建的套接字资源与之通信。
【解决方案3】:

需要更多关于它是如何运行的以及错误是什么的详细信息(我怀疑客户端在尝试访问主机时会返回网络级连接错误),但通常只使用一个端口:4444。我认为错误(未发布)是该端口正在被同一台机器上在该端口上通信的第一个程序使用。

此外,静态引用一次只允许各种套接字的一个实例存在于给定的 JVM 中。这些不能被多个线程同时使用,这些线程可能由使用这些相同(一个)静态资源的其他客户端类实现。

【讨论】:

  • 好吧,我不知道如何从这个错误中获得更多额外信息,但我可以说我尝试了以前未使用的不同端口,但没有成功。向聊天程序添加静态没有任何改变,它仍然可以正常工作。删除每个静态修饰符对第二个程序也没有任何改变。
  • 查看 Internet 上的各种网络示例,这些示例显示了一个新线程被调用,以及一个新的服务器套接字资源正在“accept()”上的该线程中创建,以管理新的客户端连接。这是一个基本的单一资源问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-28
相关资源
最近更新 更多