【问题标题】:Random errors while transferring over socket通过套接字传输时出现随机错误
【发布时间】:2014-06-10 06:49:23
【问题描述】:

好的,我有一段代码应该通过套接字发送多个文件。我在 for 循环中执行此操作的方式是打开套接字-> 传输文件-> 关闭套接字,然后对其他文件重复。上述代码如下:

for (int i = 0; i < fname.size(); i++) {
            Socket sok = new Socket("localhost",4444);
            PrintStream oos = new PrintStream(sok.getOutputStream());
            oos.println("1");
            try {

                System.out.println(fname.get(i));
                File myFile = new File(path+fname.get(i));
                byte[] mybytearray = new byte[(int) myFile.length()];

                FileInputStream fis = new FileInputStream(myFile);
                BufferedInputStream bis = new BufferedInputStream(fis);
                // bis.read(mybytearray, 0, mybytearray.length);

                DataInputStream dis = new DataInputStream(bis);
                dis.readFully(mybytearray, 0, mybytearray.length);

                OutputStream os = sok.getOutputStream();

                // Sending file name and file size to the server
                DataOutputStream doss = new DataOutputStream(os);
                doss.writeUTF(myFile.getName());
                doss.writeLong(mybytearray.length);
                doss.write(mybytearray, 0, mybytearray.length);
                doss.flush();
                sok.close();
                System.out.println("File " + fname.get(i) + " sent to Server.");

            } catch (Exception e) {
                System.err.println("File does not exist! (May not be true)   Generated Error: "+e);
            } 


            //sendFile(path+fname.get(i));
            //sock.close();
        }
    } catch (Exception e) {
        System.err.println(e);
    }

现在发生的情况是客户端没有吐出任何错误,事实上,它实际上表示文件已发送到服务器。现在服务器吐出随机错误。有时服务器会收到一些文件(不是全部),有时它不会收到任何文件,而且出现的错误也是随机的。错误是以下一项或多项:

java.io.EOFException
java.io.FileNotFoundException
java.net.SocketException: Connection reset
java.io.UTFDataFormatException

在尝试传输时,所有这些错误都发生在服务器端。我不确定这里发生了什么=/

服务器代码:

public void receiveFile() {


    try {
        int bytesRead;

        DataInputStream clientData = new DataInputStream(
                clientSocket.getInputStream());

        String fileName = clientData.readUTF();
        OutputStream output = new FileOutputStream((fileName));
        long size = clientData.readLong();
        byte[] buffer = new byte[100000];
        while (size > 0
                && (bytesRead = clientData.read(buffer, 0,
                        (int) Math.min(buffer.length, size))) != -1) {
            output.write(buffer, 0, bytesRead);
            size -= bytesRead;
        }

        output.close();
        clientData.close();

        System.out.println("File " + fileName + " received from client.");
    } catch (IOException ex) {
        System.err.println("Client error. Connection closed.     " +ex);
    }
}

堆栈跟踪:

java.io.EOFException
    at java.io.DataInputStream.readUnsignedShort(Unknown Source)
    at java.io.DataInputStream.readUTF(Unknown Source)
    at java.io.DataInputStream.readUTF(Unknown Source)
    at ClientConnection.receiveFile(ClientConnection.java:80)
    at ClientConnection.run(ClientConnection.java:46)
    at java.lang.Thread.run(Unknown Source)

1
Accepted connection : Socket[addr=/127.0.0.1,port=60653,localport=4444]
File LF-statistikkboka(Myers).pdf received from client.
1
java.io.EOFException
    at java.io.DataInputStream.readUnsignedShort(Unknown Source)
    at java.io.DataInputStream.readUTF(Unknown Source)
    at java.io.DataInputStream.readUTF(Unknown Source)
    at ClientConnection.receiveFile(ClientConnection.java:80)
    at ClientConnection.run(ClientConnection.java:46)
    at java.lang.Thread.run(Unknown Source)

File WHAT IS LEFT TO DO.docx received from client.

根据要求提供从客户端接收命令的代码

in = new BufferedReader(new InputStreamReader(
                clientSocket.getInputStream()));
        String clientSelection;
        clientSelection = in.readLine();
        System.out.println(clientSelection);
        while ((clientSelection) != null) {
            switch (clientSelection) {
            case "1":
                receiveFile();
                break;
            case "2":
                String outGoingFileName;
                while ((outGoingFileName = in.readLine()) != null) {
                    sendFile(outGoingFileName);
                }
                break;
            case "3":
                sync();
                break;
            default:
                System.out.println("Incorrect command received.");
                break;
            }
            //in.close();
            break;
        }

【问题讨论】:

  • 请显示服务器代码 - 毕竟,这就是错误所在,对吧?
  • 完成。这就是接收文件并吐出错误的函数。
  • 哪些调用引发了异常? (堆栈跟踪是什么?)
  • @ShamikulAmin 堆栈跟踪请..
  • 你能指出recieveFile的第80行是哪一行吗?

标签: java sockets reset filenotfoundexception eofexception


【解决方案1】:

罪魁祸首可能是客户端代码中的几行:

PrintStream oos = new PrintStream(sok.getOutputStream());
oos.println("1");

字符串“1”将通过连接发送,但没有服务器代码接收它,因此它与文件名混淆,文件名被解释为大小,文件数据太短,所以你会得到很多例外。由于该值是一个常数,因此传输字符串“1”似乎没有意义,因此删除这些行至少应该修复它的一部分。

【讨论】:

  • 这部分有效,它在代码的另一部分,所做的只是它的一个命令,因此它可以准备服务器以接收文件
  • 我想看看收到那个“1”的代码。问题可能就在那里。
【解决方案2】:

您必须使用 BufferedReader 读取“1”行,这将“窃取”以下一些数据。您应该使用 DataInputStream.readUTF() 从流中读取命令,使用相同的 DataInputStream 来读取以下文件,并且应该使用 DataOutputStream.writeUTF() 来编写命令,使用相同的 DataOutputStream 来发送文件。

NB 没有必要将整个文件读入内存。它只会浪费内存、增加延迟并且无法扩展。使用像接收循环这样的复制循环,以及 8k 的缓冲区。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-07-23
    • 2021-08-27
    • 1970-01-01
    • 2016-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多