简体   繁体   中英

DataOutputStream stucks

I've made a simple server application for sending images to the connected clients. I have a loop in the main thread, which accepts the incoming connections, and make a Client object from the corresponding socket. I have a list for the active clients. Every time a new picture is available, I iterate through the clients, and send them the new data. If everybody stays connecting, everything is going well. But as soon as one of the clients disconnects, the DataOutputStream's write method will stuck forever. I assumed it have to throw an exception or something, but this is not the case. I think I miss something simple, but I can't find out what. Here's my Client class' code:

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) {
            }
        }    
    }
}

It doesn't block forever. It will throw an IOException: 'connection reset' eventually. 'Forever' implies a deadlock on your part.

The 'while (!socket.isConnected());' loop is completely pointless: the socket is connected, by virtue of having been accepted. And if it wasn't, this is no way to handle it.

You shouldn't flush the stream after writing the 0xff, but you should flush it in the constructor for Client.

I don't see any reason for synchronization in Client, if it is running on its own thread, which it should be.

You should be sending to all the clients simultaneously, not iteratively, so that they all get serviced at the same time, and so that errors or slowness in one doesn't affect the others.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM