我创建了一个聊天程序,要求用户选择客户端或服务器角色。我消除此要求的方法是让每个用户都启动他们自己的服务器,他们将从那里获取消息。这应该允许我让两个客户端与另一个客户端交谈,而不必在它们之间放置服务器。
现在我已经修改了我的程序,让客户端进行发送,服务器进行接收。
请注意,在这些更改之前,两个程序之间的通信工作得非常好。但是,既然我已经更改了一些东西,那么早在我创建套接字时就会发生错误。
直到出现问题为止,我的程序流程如下:
- 程序开始
- 服务器自动启动,绑定本地6666端口
- 弹出连接配置,用户点击保存按钮(目标主机和端口被保存)
- 用户单击连接按钮
- 程序创建一个客户端线程
- 线程创建套接字并启动出站流
经过一些调试,我发现这个套接字永远不会被创建。
当流程进入此阶段(列表中的最后一项)时,仅执行“第一个测试”。
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");
}
}
输出:
Console: First test
Popup: General IO error at creating client socket
Console: Second test
Console: NPE at `outbound.close()`
我假设 NPE 是第一个错误的结果,考虑到在创建PrintWriter
. 还应注意,显示第一个错误大约需要 10 秒。
一开始我以为可能是因为本地服务器和与其他客户端的连接都使用了6666端口,但在6667端口上创建链接后,问题仍然存在。审查后这是有道理的。
当我的调试器指向outbound
初始化的行时(在“第二次测试”消息之后,套接字具有 value null
。
我的问题是:为什么不能创建套接字?该文档仅指定
IOException - 如果创建套接字时发生 I/O 错误。
这没什么用。
完整的源代码可以在这里找到以获得更好的概述。
编辑:从第一个主要错误打印堆栈跟踪。
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)