简体   繁体   English

DataOutputStream卡住

[英]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. 我在主线程中有一个循环,该循环接受传入的连接,并从相应的套接字中创建一个Client对象。 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. 但是,一旦其中一个客户端断开连接,DataOutputStream的write方法将永远卡住。 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. 它将抛出IOException:最终“连接重置”。 'Forever' implies a deadlock on your part. “永远”意味着您陷入僵局。

The 'while (!socket.isConnected());' '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. 编写0xff之后,不应刷新流,而应在Client的构造函数中刷新流。

I don't see any reason for synchronization in Client, if it is running on its own thread, which it should be. 我没有看到Client中进行同步的任何理由,如果它在它自己的线程上运行,应该是这样。

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. 您应该同时发送所有客户端,而不要反复发送,以便它们都在同一时间得到服务,并且一个客户端的错误或运行缓慢不会影响其他客户端。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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