java 无法创建套接字,抛出 IOException

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14651894/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 16:58:41  来源:igfitidea点击:

Socket can't be created, throws IOException

javasocketsioexception

提问by Jeroen Vannevel

I've created a chat program which required the user to select either the client or server role. My approach at removing this requirement is to have every user start their own server where they'll get messages from. This should allow me to have two clients talk to the the other without having to put a server in between them.

我创建了一个聊天程序,它要求用户选择客户端或服务器角色。我消除这个要求的方法是让每个用户启动他们自己的服务器,他们将从那里获取消息。这应该允许我让两个客户端相互通信,而不必在它们之间放置服务器。

Right now I've modified my program in such a way that the client side does the sending and the server does the receiving.

现在我已经修改了我的程序,客户端进行发送,服务器进行接收。

Note that communication between the two programs worked perfectly fine up untill these changes. However, now that I've changed some stuff an error occurs as early as when I create a socket.

请注意,在这些更改之前,两个程序之间的通信工作得非常好。但是,现在我已经更改了一些东西,早在我创建套接字时就会发生错误。

The flow of my program untill the problem is as follows:

我的程序流程直到问题如下:

  • Program starts
  • Server starts automatically, binded to local port 6666
  • Connection config pops up, user clicks the save button (target host and port are saved)
  • User clicks the connect button
  • Program creates a client thread
  • Thread creates the socket and initiates the outbound stream
  • 程序开始
  • 服务器自动启动,绑定本地6666端口
  • 弹出连接配置,用户点击保存按钮(目标主机和端口被保存)
  • 用户点击连接按钮
  • 程序创建一个客户端线程
  • 线程创建套接字并启动出站流

After some debugging I've found that this socket is never created.

经过一些调试后,我发现这个套接字从未被创建。

When the flow enters this stage (last item in the list), only the 'First test' gets executed.

当流程进入此阶段(列表中的最后一项)时,只会执行“第一个测试”。

public void run() {
            System.out.println("First test");
            createConnection();
            System.out.println("Second test");
            initiateIO();
    }

private void createConnection() {
        try {
            socket = new Socket(host, port);
        } catch (UnknownHostException e) {
            OutputUtil.showErrorMessage("Couldn't bind socket to unknown host", "Unknown host");
        } catch (IOException e) {
            OutputUtil.showErrorMessage("General IO error at creating client socket", "IO error");
        }
    }

private void initiateIO() {
        try {
            outbound = new PrintWriter(socket.getOutputStream(), true);
        } catch (IOException e) {
            OutputUtil.showErrorMessage("Couldn't load IO streams from client", "IO Error");
        }
    }

Output:

输出:

Console: First test
Popup: General IO error at creating client socket
Console: Second test
Console: NPE at `outbound.close()`

I'm assuming the NPE is a result of the first error, considering a method from the socket is invoked when creating the PrintWriter. It should also be noted that it takes around 10 seconds to show the first error.

我假设 NPE 是第一个错误的结果,考虑到在创建PrintWriter. 还应该注意的是,显示第一个错误大约需要 10 秒。

At first I thought the error might be introduced because both the local server and the connection with the other client use port 6666, but after creating a link on port 6667 the problem still occurred. Which makes sense upon review.

一开始我以为这个错误可能是因为本地服务器和与其他客户端的连接都使用了6666端口,但是在6667端口上创建了一个链接后,问题仍然出现。经,这是有道理的。

When my debugger points at the line where outboundis initialized (after the "second test" message, socket has value null.

当我的调试器指向outbound初始化所在的行时(在“第二次测试”消息之后,socket 具有 value null.

My question is: why can't the socket be created? The documentation only specifies

我的问题是:为什么不能创建套接字?该文档仅指定

IOException - if an I/O error occurs when creating the socket.

IOException - 如果创建套接字时发生 I/O 错误。

which isn't of much use.

这没有多大用处。

Full source code can be found herefor a better overview.

完整的源代码可以在这里找到以获得更好的概述。

Edit: Printed the stacktrace from the first, main error.

编辑:从第一个主要错误打印堆栈跟踪。

java.net.ConnectException: Connection timed out: connect
    at java.net.DualStackPlainSocketImpl.connect0(Native Method)
    at java.net.DualStackPlainSocketImpl.socketConnect(Unknown Source)
    at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source)
    at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source)
    at java.net.AbstractPlainSocketImpl.connect(Unknown Source)
    at java.net.PlainSocketImpl.connect(Unknown Source)
    at java.net.SocksSocketImpl.connect(Unknown Source)
    at java.net.Socket.connect(Unknown Source)
    at java.net.Socket.connect(Unknown Source)
    at java.net.Socket.<init>(Unknown Source)
    at java.net.Socket.<init>(Unknown Source)
    at core.Client.createConnection(Client.java:30)
    at core.Client.run(Client.java:64)
    at java.lang.Thread.run(Unknown Source)

回答by user207421

This is a firewall problem. The target port you specified wasn't open in the target's firewall.

这是防火墙问题。您指定的目标端口未在目标的防火墙中打开。

The server may alsonot have been running, but if that was the only problem it would have been 'connection refused', not 'connection timed out: connect'.

服务器可能不会一直运行,但如果这是唯一的问题,那将是“连接被拒绝”,而不是“连接超时:连接”。

回答by Ste

Socket are client/server by definition. You always need a ServerSocket that bind to the 6666 port and listen for incoming connection from the client Socket.

根据定义,套接字是客户端/服务器。您始终需要一个绑定到 6666 端口并侦听来自客户端 Socket 的传入连接的 ServerSocket。

Did one of the two client succesfully bound a ServerSocket?

两个客户端之一是否成功绑定了 ServerSocket?