【问题标题】:java DataInputStream read() stop and do not proceedjava DataInputStream read() 停止并且不继续
【发布时间】:2014-07-16 05:47:45
【问题描述】:
  • 我想发送和接收一个对象并归档顺序是

    1. client -> server by ObjectOut(In)putStream

    2. client -> server String(file name) by DataIn(Out)putStrean writeUTF

    3. client -> server by BufferedIn(Out)putStream

    4. 服务器 -> 客户端通过 ObjectOut(In)putStream

但是当代码达到 3 个写入文件时需要永远(我认为...它正在等待),关键代码是

byte[] data = new byte[BUFFER_SIZE];
while ((length = bis.read(data)) != -1) {
    bos.write(data, 0, length);
    System.out.println(length);
}

bis(BufferedInputStream).read() 当我打印输出的长度时不要继续

4096
4096
879

那就等着吧……

有没有人知道问题或解决方案是什么?

服务器线程

public void run() {

    System.out.println("\n New FileUploadServer thread started");
    msg = (Message) objComm.recvObject(clientSocket);
    System.out.println("server get message");
    if (checkState(msg.getState()))
        System.out.println(clientAddr + " session over");

    System.out.println("");
}

private boolean checkState(int _state) {
    switch (_state) {
        case ST_EXCEL_FILE:
            return receiveExcel();
        default:
            return false;
    }
}


private boolean receiveExcel() {

    Message sendMsg = receiveStr();
    System.out.println("receiveStr() success");
    BufferedInputStream bis;
    DataOutputStream dos;
    DataInputStream dis;
    FileOutputStream fos;
    BufferedOutputStream bos;

    VoteInfo sendVoteInfo = (VoteInfo) msg.getObj();

    try {
        dis = new DataInputStream(clientSocket.getInputStream());
        dos = new DataOutputStream(clientSocket.getOutputStream());
        // check file name extension is "xls" or "xlsx"
        String fName = dis.readUTF();


        int idx = fName.lastIndexOf(".");
        String extension = fName.substring(idx + 1, fName.length());
        if (!excelFileCheck(extension))
            return false;

        dos.writeUTF("read_ok");
        dos.flush();
        System.out.println("File name: " + fName);
        File f = new File(EXCEL_FILE_DIR + fName);

        fos = new FileOutputStream(f);
        bos = new BufferedOutputStream(fos);
        bis = new BufferedInputStream(clientSocket.getInputStream());

        int length;
        byte[] data = new byte[BUFFER_SIZE];
        while ((length = bis.read(data)) != -1) {
            bos.write(data, 0, length);
            System.out.println(length);
        }
        bos.flush();
        // send success message to web server
        System.out.println("kangji2");

        objComm.sendObject(sendMsg, clientSocket);


        System.out.println("File receive success!");

        if (!dataToDB.excelToDB(EXCEL_FILE_DIR + fName, extension)) {
            //delete all db related to this excel file here
            return false;
        } else {


        }
        bos.close();
        fos.close();
        dis.close();

        clientSocket.close();

        // send candidates information to DB server
        return makeResult(sendVoteInfo);

    } catch (IOException e) {
        System.out.println("ReceiveExcel error");
        e.printStackTrace();
    }
    return false;
}


public class ObjectComm {

    private Message receiveMsg = null;
    private ObjectOutputStream out = null;
    private ObjectInputStream in = null;

    public Message commObject(Message _sendMsg, Socket _clntSocket) {

        if (!_clntSocket.isConnected()) {
            System.out.println("clnt Socket not connected");
            return null;
        }

        try {
            out = new ObjectOutputStream(_clntSocket.getOutputStream());
            out.writeObject(_sendMsg);
            out.flush();

            System.out.println("kangji1");
            in = new ObjectInputStream(_clntSocket.getInputStream());
            receiveMsg = (Message) in.readObject();
            System.out.println("kangji2");
            return receiveMsg;
        } catch (Exception e) {
            System.out.println("commObject err");
            e.printStackTrace();
            return null;
        }

    }

    public boolean sendObject(Message _msg, Socket _clntSocket) {
        if (!_clntSocket.isConnected()) {
            System.out.println("clnt Socket not connected");
            return false;
        }

        try {
            out = new ObjectOutputStream(_clntSocket.getOutputStream());
            out.writeObject(_msg);
            out.flush();

            return true;
        } catch (IOException e) {
            System.out.println("Object comm send err");
            e.printStackTrace();
            return false;
        }
    }

    public Message recvObject(Socket _clntSocket) {
        if (!_clntSocket.isConnected()) {
            System.out.println("clnt Socket not connected");
            return null;
        }

        try {
            in = new ObjectInputStream(_clntSocket.getInputStream());
            receiveMsg = (Message) in.readObject();
            return receiveMsg;

        } catch (Exception e) {
            System.out.println("Object comm recvObject err");
            e.printStackTrace();
            return null;
        }
    }

}

【问题讨论】:

    标签: java sockets object file-io datainputstream


    【解决方案1】:

    您是否关闭了客户端(发送方,或与您的输入流相反的任何地方)的连接? BufferedInputStream 中的 read(byte[], int, int ) 将在到达流末尾时返回。

    http://docs.oracle.com/javase/7/docs/api/java/io/BufferedInputStream.html#read(byte[],%20int,%20int)

    【讨论】:

    • 我想如果我关闭缓冲区,那么套接字也会关闭,不是吗?
    • 好吧,我没有在你的代码中看到 close() 调用 BufferedInputStream .. 实际上你不应该那样做。您的代码需要读取输入流,直到 read() 返回 -1,然后您可以在代码末尾关闭输入流,而不是在从输入流中读取字节期间。尝试在代码通过输入流读取字节的相反部分添加套接字关闭逻辑,如果我的建议有效,请重试。
    • 正如你所说,如果我添加 close() 等待结束,但问题是在 close() 之后,套接字也关闭了。所以在 close() 之后我无法从服务器接收或获取消息
    • 似乎您与 clientSocket 连接的客户端已完成发送数据,并且什么都没有了。因此,每次您的代码尝试通过 read(byte[], int, int) 读取字节时,方法将返回 0(零),因为没有要读取的内容并且读取实际上被阻止。这就是为什么您在 4096 4096 879 之后看不到任何数据的原因。正如您所评论的,如果您想继续使用该连接的 clientSocket,那么是的,您不应该关闭套接字。只需更改 while((length = bis.read(data)) > 0) 之类的 while 条件 ...您也许可以避免当前的问题,
    • 虽然您的网络或客户端远程进程有可能由于某种原因实际上被阻止并且没有发送任何临时内容..这种情况下即使还有更多字节要读取,您的读取过程也将完成.
    【解决方案2】:
    • 客户端 -> 由 ObjectOut(In)putStream 提供的服务器
    • client -> server String(file name) by DataIn(Out)putStrean writeUTF
    • 客户端 -> BufferedIn(Out)putStream 的服务器
    • 服务器 -> ObjectOut(In)putStream 客户端

    这里的东西太多了。

    在流堆栈的不同级别播放流根本不起作用。

    如果您想发送对象,请使用ObjectInput/OutputStreams 来表示所有内容。按如下方式构造它们:

    new ObjectOutputStream(new BufferedOutputStream(...))
    

    new ObjectInputStream(new BufferedInputStream(...))
    

    writeObject(); 发送对象,用writeObject()writeUTF(); 发送字符串,通过ObjectOutputStream.write(); 发送字节数组,并在另一端使用ObjectInputStream 的互补方法。

    【讨论】:

    • 你到底尝试了什么?什么代码?将其编辑到您的问题中。
    猜你喜欢
    • 2021-02-05
    • 1970-01-01
    • 1970-01-01
    • 2015-05-29
    • 1970-01-01
    • 2018-08-22
    • 2020-12-30
    • 2018-10-10
    • 1970-01-01
    相关资源
    最近更新 更多