简体   繁体   中英

Sending Multiple Files Over a Java Socket

I am trying to get a program working where a client sends the same file to the server 100 times and then checks to make sure all 100 files are the same as the original. Right now I cant get it to work because the server reads some arbitrary amount of bytes from the client and it causes some files to have too many bytes in them and I'm not sure how to proceed. Right now it will send all 100 files properly but some files just have too much stuff in them.

Client code

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);
}

Server Code

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();

TCP is a byte stream. It has no concept of messages. As such, you need to frame the file data in such a way that the receiver knows where one file ends and the next begins. In this case, you need to send the file size before sending the file data, so the receiver knows how many bytes to expect per file.

Also, you are not paying attention properly to the number of bytes that read() tells you were actually read each time you call it. You are giving it a large buffer, but there is no guarantee that the entire buffer will be filled up. Especially at the end of a file.

And don't transfer binary file data using strings!

Try something more like this instead:

Client:

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);

Server:

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();

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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