1. Introduction
1.绪论
In this quick tutorial, we’ll learn the causes of SocketException with an example.
在这个快速教程中,我们将通过一个例子了解SocketException的原因。
We’ll also, of course, discuss how to handle the exception.
当然,我们也会讨论如何处理这种例外。
2. Causes of SocketException
2.造成SocketException的原因
The most common cause of SocketException is writing or reading data to or from a closed socket connection. Another cause of it is closing the connection before reading all data in the socket buffer.
导致SocketException的最常见原因是向已关闭的socket连接写入或读取数据。其另一个原因是在读取套接字缓冲区中的所有数据之前关闭连接。
Let’s take a closer look at some common underlying reasons.
让我们仔细看看一些常见的根本原因。
2.1. Slow Network
2.1.慢速网络
A poor network connection might be the underlying problem. Setting a higher socket connection timeout can decrease the rate of SocketException for slow connections:
网络连接不佳可能是根本问题。设置一个较高的套接字连接超时可以减少慢速连接的SocketException的发生率。
socket.setSoTimeout(30000); // timeout set to 30,000 ms
2.2. Firewall Intervention
2.2.防火墙干预
A network firewall can close socket connections. If we have access to the firewall, we can turn it off and see if it solves the problem.
一个网络防火墙可以关闭套接字连接。如果我们能够访问防火墙,我们可以将其关闭,看看是否能够解决问题。
Otherwise, we can use a network monitoring tool such as Wireshark to check firewall activities.
否则,我们可以使用网络监控工具,如Wireshark来检查防火墙活动。
2.3. Long Idle Connection
2.3.长时间空闲连接
Idle connections might get forgotten by the other end (to save resources). If we have to use a connection for a long time, we can send heartbeat messages to prevent idle state.
闲置的连接可能会被另一端遗忘(以节省资源)。如果我们必须长时间使用一个连接,我们可以发送心跳信息以防止空闲状态。
2.4. Application Error
2.4.应用错误
Last but not least, SocketException can occur because of mistakes or bugs in our code.
最后但并非最不重要的是,SocketException会因为我们代码中的错误或漏洞而发生。
To demonstrate this, let’s start a server on port 6699:
为了证明这一点,让我们在6699端口启动一个服务器。
SocketServer server = new SocketServer();
server.start(6699);
When the server is started, we’ll wait for a message from the client:
当服务器启动时,我们将等待来自客户端的消息。
serverSocket = new ServerSocket(port);
clientSocket = serverSocket.accept();
out = new PrintWriter(clientSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String msg = in.readLine();
Once we get it, we’ll respond and close the connection:
一旦我们得到它,我们将回应并关闭连接:。
out.println("hi");
in.close();
out.close();
clientSocket.close();
serverSocket.close();
So, let’s say a client connects to our server and sends “hi”:
因此,假设一个客户连接到我们的服务器并发送 “嗨”。
SocketClient client = new SocketClient();
client.startConnection("127.0.0.1", 6699);
client.sendMessage("hi");
So far, so good.
到目前为止,一切都很好。
But, if the client sends another message:
但是,如果客户发送另一个信息。
client.sendMessage("hi again");
Since the client sends “hi again” to the server after the connection is aborted, a SocketException occurs.
由于客户端在连接中止后向服务器发送了“hi again”,因此发生了SocketException。
3. Handling of a SocketException
3.对SocketException的处理
Handling SocketException is pretty easy and straightforward. Similar to any other checked exception, we must either throw it or surround it with a try-catch block.
处理SocketException是相当简单和直接的。与其他检查过的异常类似,我们必须扔掉它或者用一个 try-catch 块来包围它。
Let’s handle the exception in our example:
让我们来处理我们的例子中的异常。
try {
client.sendMessage("hi");
client.sendMessage("hi again");
} catch (SocketException e) {
client.stopConnection();
}
Here, we’ve closed the client connection after the exception occurred. Retrying won’t work, because the connection is already closed. We should start a new connection instead:
这里,我们在异常发生后关闭了客户端连接。重试是不行的,因为连接已经关闭。我们应该启动一个新的连接,而不是:。
client.startConnection("127.0.0.1", 6699);
client.sendMessage("hi again");
4. Conclusion
4.总结
In this article, we had a look at what causes SocketException and how to handle it.
在这篇文章中,我们看了一下导致SocketException的原因以及如何处理它。
As always, the code is available over on Github.
像往常一样,代码可以在Github上获得。