«1. Введение
В этом кратком руководстве мы рассмотрим причины SocketException на примере.
Мы также, конечно, обсудим, как обрабатывать исключение.
2. Причины SocketException
Наиболее распространенной причиной SocketException является запись или чтение данных в или из соединения с закрытым сокетом. Другой причиной этого является закрытие соединения до чтения всех данных в буфере сокета.
Давайте подробнее рассмотрим некоторые общие причины.
2.1. Медленная сеть
Причиной проблемы может быть плохое сетевое соединение. Установка большего тайм-аута подключения к сокету может снизить частоту SocketException для медленных подключений:
socket.setSoTimeout(30000); // timeout set to 30,000 ms
2.2. Вмешательство брандмауэра
Сетевой брандмауэр может закрывать сокетные соединения. Если у нас есть доступ к брандмауэру, мы можем отключить его и посмотреть, решит ли он проблему.
В противном случае мы можем использовать инструмент мониторинга сети, такой как Wireshark, для проверки активности брандмауэра.
2.3. Длинное бездействующее соединение
Бездействующие соединения могут быть забыты на другом конце (для экономии ресурсов). Если нам нужно использовать соединение в течение длительного времени, мы можем отправлять сообщения пульса, чтобы предотвратить состояние простоя.
2.4. Ошибка приложения
И последнее, но не менее важное: SocketException может возникнуть из-за ошибок или ошибок в нашем коде.
Чтобы продемонстрировать это, давайте запустим сервер на порту 6699:
SocketServer server = new SocketServer();
server.start(6699);
Когда сервер будет запущен, мы будем ждать сообщения от клиента:
serverSocket = new ServerSocket(port);
clientSocket = serverSocket.accept();
out = new PrintWriter(clientSocket.getOutputStream(), true);
in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String msg = in.readLine();
Получив его, мы отвечу и закрою соединение:
out.println("hi");
in.close();
out.close();
clientSocket.close();
serverSocket.close();
Итак, допустим, клиент подключается к нашему серверу и отправляет «привет»:
SocketClient client = new SocketClient();
client.startConnection("127.0.0.1", 6699);
client.sendMessage("hi");
Пока все хорошо.
Но, если клиент отправляет другое сообщение:
client.sendMessage("hi again");
Поскольку клиент снова отправляет «привет» на сервер после разрыва соединения, возникает исключение SocketException.
3. Обработка SocketException
Обработка SocketException довольно проста и понятна. Подобно любому другому проверенному исключению, мы должны либо выдать его, либо окружить блоком try-catch.
Давайте обработаем исключение в нашем примере:
try {
client.sendMessage("hi");
client.sendMessage("hi again");
} catch (SocketException e) {
client.stopConnection();
}
Здесь мы закрыли клиентское соединение после возникновения исключения. Повторная попытка не сработает, так как соединение уже закрыто. Вместо этого мы должны установить новое соединение:
client.startConnection("127.0.0.1", 6699);
client.sendMessage("hi again");
4. Заключение
В этой статье мы рассмотрели, что вызывает SocketException и как с ним справиться.
Как всегда, код доступен на Github.