【问题标题】:Sending Multiple Files Over a Java Socket通过 Java 套接字发送多个文件
【发布时间】:2020-09-29 20:50:36
【问题描述】:

我正在尝试让一个程序运行,其中客户端将相同的文件发送到服务器 100 次,然后检查以确保所有 100 个文件都与原始文件相同。现在我无法让它工作,因为服务器从客户端读取了一些任意数量的字节,这导致一些文件中有太多字节,我不知道如何继续。现在它将正确发送所有 100 个文件,但有些文件中的内容太多了。

客户端代码

String sentence;
    InetAddress host = InetAddress.getLocalHost();
    Socket clientSocket = new Socket(host, 6789);
    DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());

    long startTime, endTime, tGap, totalTime;
    byte[] sendData;
    int filesSent = 0;

    File fs = new File("Test1.txt");

    int fileLength = (int) fs.length();
    totalTime = 0;

    while (filesSent < 100) {
        FileInputStream fin = new FileInputStream(fs);
        int numBytes = 0;
        System.out.println("Sending file to server...");
        sendData = new byte[1024];
        if (fileLength < 1024) {
            numBytes = fin.read(sendData, 0, fileLength);
        } else {
            numBytes = fin.read(sendData, 0, 1024);
        }

        startTime = System.currentTimeMillis();
        int count = 0;
        while (numBytes != -1) {
            count += numBytes;
            System.out.println(numBytes);
            sentence = new String(sendData);
            outToServer.writeBytes(sentence);
            numBytes = fin.read(sendData, 0, 1024);
        }
        System.out.println(count);
        endTime = System.currentTimeMillis();
        tGap = endTime - startTime;
        totalTime = totalTime + tGap;
        System.out.println("Finished run " + filesSent + " with a time of " + tGap);
        filesSent++;
        fin.close();
        outToServer.flush();
    }
    clientSocket.close();

    System.out.println("I am done to send " + filesSent + " times file, and the average time is: " + (double) totalTime / filesSent);
}

服务器代码

String clientSentence;
    int filesRecieved = 0;
    ServerSocket welcomeSocket = new ServerSocket(6789);
    int numError = 0;
    int numBytes;
    char check = 'a';
    System.out.println("I am starting now....");

    long startTime, endTime, tGap, totalTime;
    totalTime = 0;

    Socket connectionSocket;
    connectionSocket = welcomeSocket.accept();
    BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));

    while(filesRecieved < 100) {
        FileOutputStream outPut = new FileOutputStream("receivedFile" + filesRecieved + ".txt");
        char[] receiveData = new char[1024];
        numBytes = inFromClient.read(receiveData, 0, 1024);
        while(numBytes != 1024){
            numBytes += inFromClient.read(receiveData,0,1024-numBytes);
        }
        System.out.println("OG Bytes:" + numBytes);
        startTime = System.currentTimeMillis();

        int count = 0;
        while (numBytes != -1 && count < 105942) {
            try {
                count += numBytes;
                clientSentence = new String(receiveData, 0, numBytes);
                outPut.write(clientSentence.getBytes(), 0, numBytes);
                System.out.println(numBytes);
                numBytes = inFromClient.read(receiveData, 0, 1024);
                System.out.println(count);
            }catch(Exception e){
                break;
            }
        }
        outPut.close();
        endTime = System.currentTimeMillis();
        tGap = endTime - startTime;
        totalTime = totalTime + tGap;
        System.out.println("I have received" + "receivedFile" + filesRecieved + ".txt using time = " + tGap);
        filesRecieved++;
    }

    connectionSocket.close();

    System.out.println("I am done now..." + "and the average time used to receive each copy is: " + totalTime / filesRecieved);
    welcomeSocket.close();

【问题讨论】:

  • 我发现代码阅读起来有些复杂,而且我确信在服务器代码的某些循环中存在读取错误。看这个单个文件的例子:stackoverflow.com/a/9548429/13211030。如果您在将其转换为 100 个文件(或任何数量,动态输入更好)时遇到任何问题,请告诉我们
  • Remy 已经说过了,但我想再次强调 Java 不是 C — 将字节转换为字符串 会损坏您的数据。 Java 中的字符串用于文本,而不是二进制数据。

标签: java file sockets


【解决方案1】:

TCP 是一个字节流。它没有消息的概念。因此,您需要以这样一种方式构建文件数据,即接收者知道一个文件的结束位置和下一个文件的开始位置。在这种情况下,您需要在发送文件数据之前发送文件大小,以便接收方知道每个文件需要多少字节。

此外,您没有正确注意read() 告诉您每次调用它时实际读取的字节数。你给它一个很大的缓冲区,但不能保证整个缓冲区都会被填满。尤其是在文件的末尾。

并且不要使用字符串传输二进制文件数据!

试试类似的方法:

客户:

File fs = new File("Test1.txt");
long fileLength = fs.length();

InetAddress host = InetAddress.getLocalHost();
Socket clientSocket = new Socket(host, 6789);
DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());

long startTime, endTime, tGap, totalTime = 0;
byte[] sendData = new byte[1024];
int numBytes, filesSent = 0;

while (filesSent < 100) {
    FileInputStream fin = new FileInputStream(fs);
    long thisFileLength = fileLength;

    System.out.println("Sending file to server...");
    startTime = System.currentTimeMillis();

    outToServer.writeLong(thisFileLength);

    while (thisFileLength > 0) {
        if (thisFileLength < sendData.length) {
            numBytes = fin.read(sendData, 0, (int) thisFileLength);
        } else {
            numBytes = fin.read(sendData, 0, sendData.length);
        }

        System.out.println(numBytes);
        if (numBytes < 1) {
            break;
        }

        outToServer.write(sendData, 0, numBytes);
        thisFileLength -= numBytes;
    }

    outToServer.flush();

    endTime = System.currentTimeMillis();
    tGap = endTime - startTime;
    totalTime = totalTime + tGap;
    System.out.println("Finished run " + filesSent + " with a time of " + tGap);
    filesSent++;

    fin.close();

    if (thisFileLength > 0) {
        break;
    }
}

clientSocket.close();

System.out.println("I am done to send " + filesSent + " times file, and the average time is: " + (double) totalTime / filesSent);

服务器:

ServerSocket welcomeSocket = new ServerSocket(6789);
System.out.println("I am starting now....");

Socket connectionSocket;
connectionSocket = welcomeSocket.accept();
DataInputStream inFromClient = new DataInputStream(new BufferedInputStream(connectionSocket.getInputStream()));

long startTime, endTime, tGap, totalTime = 0;
byte[] receiveData = new byte[1024];
int numBytes, filesRecieved = 0;

while (filesRecieved < 100) {
    string filename = "receivedFile" + filesRecieved + ".txt";
    FileOutputStream outPut = new FileOutputStream(filename);

    startTime = System.currentTimeMillis();

    long fileLength = inFromClient.readLong();
    System.out.println("OG Bytes: " + fileLength);

    while (fileLength > 0) {
        if (fileLength < receiveData.length) {
            numBytes = inFromClient.read(receiveData, 0, (int) fileLength);
        }
        else {
            numBytes = inFromClient.read(receiveData, 0, receiveData.length);
        }

        if (numBytes < 1) {
            break;
        }

        try {
            outPut.write(receiveData, 0, numBytes);
            System.out.println(numBytes);
        }
        catch (Exception e) {
            break;
        }

        fileLength -= numBytes;
    }

    outPut.close();

    endTime = System.currentTimeMillis();
    tGap = endTime - startTime;
    totalTime = totalTime + tGap;
    System.out.println("I have received " + filename + " using time = " + tGap);
    filesRecieved++;

    if (fileLength > 0) {
        break;
    }
}

connectionSocket.close();

System.out.println("I am done now... and the average time used to receive each copy is: " + totalTime / filesRecieved);
welcomeSocket.close();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-28
    • 1970-01-01
    • 1970-01-01
    • 2016-12-08
    • 1970-01-01
    • 1970-01-01
    • 2011-02-24
    相关资源
    最近更新 更多