2

好的,所以我有一段代码应该通过套接字发送多个文件。我在 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;
        }
4

2 回答 2

0

You must be reading the '1' line with a BufferedReader, which will 'steal' some of the following data. You should use DataInputStream.readUTF() to read commands from the stream, with the same DataInputStream you use to read the following file, and you should use DataOutputStream.writeUTF() to write the command, using the same DataOutputStream you use to send the file.

NB there's no need to read the entire file into memory. It just wastes memory, adds latency, and doesn't scale. Use a copy loop like your receive loop, and a buffer of say 8k.

于 2014-04-25T01:09:20.730 回答
0

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

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

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

于 2014-04-24T19:41:42.850 回答