DataOutputStream застревает
Я сделал простое серверное приложение для отправки изображений на подключенные клиенты. У меня есть цикл в главном потоке, который принимает входящие соединения и делает объект клиента из соответствующего сокета. У меня есть список для активных клиентов. Каждый раз, когда появляется новая картинка, я перебираю клиентов и отправляю им новые данные. Если все остаются на связи, все идет хорошо. Но как только один из клиентов отключается, метод записи DataOutputStream застревает навсегда. Я предполагал, что это должно вызвать исключение или что-то, но это не так. Я думаю, что скучаю по чему-то простому, но не могу понять, что. Вот код моего класса клиента:
package hu.rothens.webcam;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
public class Client {
private static int next_id = 0;
private int id;
private Socket socket;
private WebcamServer ws;
private DataOutputStream dos;
public Client(Socket socket, WebcamServer ws, int width, int height) throws IOException {
this.socket = socket;
this.ws = ws;
id = next_id++;
while (!socket.isConnected());
dos = new DataOutputStream(socket.getOutputStream());
dos.writeInt(width);
dos.writeInt(height);
}
public synchronized void sendImage(byte[] array) {
try {
System.out.println(id);
//the code will stuck somewhere after this line
dos.writeByte(0xFF);
dos.flush();
dos.writeInt(array.length);
dos.write(array);
dos.flush();
} catch (IOException e) {
System.out.println(e); //it won't get here
ws.removeClient(this);
try {
socket.close();
} catch (Exception ex) {
}
}
}
}
1 ответ
Это не блокирует навсегда. Это вызовет IOException: "сброс соединения" в конце концов. "Навсегда" подразумевает тупик с вашей стороны.
'While (! Socket.isConnected());' Цикл совершенно бессмысленный: сокет подключен, благодаря тому, что был принят. И если это не так, это не способ справиться с этим.
Вы не должны очищать поток после записи 0xff, но вы должны очищать его в конструкторе для клиента.
Я не вижу никакой причины для синхронизации в клиенте, если он работает в своем собственном потоке, что и должно быть.
Вы должны отправлять всем клиентам одновременно, а не итеративно, чтобы все они обслуживались одновременно, и чтобы ошибки или медлительность в одном не влияли на других.