通过TCP java进行文件传输

时间:2013-12-27 05:14:48

标签: java sockets file-io tcp

我正在进行实验,以了解自己对通过服务器和客户端之间的TCP连接传输任何文件的好奇心

我的项目是“服务器接收文件”和“客户端发送该文件”

但似乎出了问题,客户端可以发送整个文件,服务器端也可以接收整个文件但是在服务器端接收后文件无法打开就像读取时出错了发送它的块

你们可以检查我是否做错了吗

这是我的服务器端代码

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;


public class TFServer2 {

private static ServerSocket servSock;
private static int port;

public static void main(String[] args) throws NumberFormatException, IOException{

    if(args.length < 1){
        port = 1500;
    }else{
        port = Integer.parseInt(args[0]);
    }

    servSock = new ServerSocket(port);
    int i = 1;

    while(true){
        System.out.println("Listening connection...");
        Socket client = servSock.accept();

        System.out.println("Client " + i + "requires connection!");
        ClientHandler ch = new ClientHandler(client);
        ch.setNumber(i++);
        ch.start();
    }

}

}

这里是ClientHandler

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.Socket;


public class ClientHandler extends Thread{

private int i;

private Socket client;
private ObjectInputStream sInt;
private String fileName;
private int file_size;
private File file;
private FileOutputStream outStr;
private BufferedOutputStream bos;


public ClientHandler(Socket client) throws IOException{
    this.client = client;

    this.sInt = new ObjectInputStream(this.client.getInputStream());
}

public void setNumber(int i){
    this.i = i;
}

public void run(){

    try {
        System.out.println("Client " + i + ": " + client.getInetAddress() + " connected on port " + client.getPort());

        //get filename
        fileName = (String) sInt.readObject();
        String[] str = fileName.split(".");

        //get file size
        file_size = sInt.readInt();

        //open file
        file = new File("D:\\practice_java_network\\TransferFileServer\\Download\\" + fileName);

        //create file output stream
        outStr = new FileOutputStream(file);

        //create buffered output
        bos = new BufferedOutputStream(outStr);

        byte[] buffer = null;
        int total_read_len = 0;

        //receiving file loop
        while( sInt.readBoolean() ){
            buffer = (byte[]) sInt.readObject();
            total_read_len += buffer.length;
            bos.write(buffer);

            System.out.println("Receive: " + (float)total_read_len/file_size*100 + "%");
        }

        //close all connection
        bos.close();
        outStr.close();
        sInt.close();
        client.close();

        System.out.println("connection with client " + i + " closed");
        System.out.println("Done recieving file");
        System.out.println("File contained at: " + file.toPath());

        return;
    } catch (IOException | ClassNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }


}

}

这是客户端的代码

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;


public class TFClientv2 {

private static Socket socket;
private static int port;
private static String host;
private static String fileName;
private static File file;
private static BufferedInputStream bis;
private static ObjectOutputStream sOut;

public static void main(String[] args) {

    Scanner sc = new Scanner(System.in);

    try{
        System.out.println("Args: " + args.length);

        //check arguments
        if(args.length < 1)
            host = "somehost";
        else
            host = args[0];
        System.out.println("Host: " + host);

        if(args.length < 2)
            port = 1500;
        else
            port = Integer.parseInt(args[1]);
        System.out.println("port: " + port);

        if(args.length < 3){
            System.out.print("File: ");
            fileName = sc.nextLine();
            fileName = insert(fileName, '\\');
        }else{
            fileName = insert(args[2], '\\');
        }
        //done checking arguments



        //test if the file does exist
        file = new File(fileName);
        if(!file.exists()){
            System.out.println("There's no such file!");
            System.exit(1);
        }

        /*
         * create input Stream to read file
         */
        bis = new BufferedInputStream(new FileInputStream(file));



        /*
         * connect to host preparing to send the file
         * and create get outputStream
         */
        System.out.println("Opening connection with host: " + host);
        socket = new Socket(host, port);
        System.out.println("Connected to host " + socket.getInetAddress());
        sOut = new ObjectOutputStream(socket.getOutputStream());

        /*
         * extract only exact file name(not path)
         * and send to server
         */
        String[] str = fileName.split("\\\\");
        sOut.writeObject(str[str.length-1]);
        System.out.println("Prepairing file \"" + str[str.length-1] + "\" to be sent");


        /*
         * these variables necessary to be used
         * for sending file
         */
        int file_len = (int) file.length();
        int buff_size = 1024;
        int bytesRead = 0;
        int total_read_len = 0;
        byte[] buffer = new byte[buff_size];

        int file_len_2 = file_len;

        //tell server to know size of the file
        sOut.writeInt(file_len);

        //This one copy the file in exact size
        //begin read and send chunks of file in loop
        while( file_len_2 > 0 ){
            if( file_len_2 < buff_size ){
                buffer = new byte[file_len_2];
                bytesRead = bis.read(buffer);
            }else{
                bytesRead = bis.read(buffer);
            }

            file_len_2 -= bytesRead;
            total_read_len += bytesRead;
            sOut.writeBoolean(true);
            sOut.writeObject(buffer);
            System.out.println("Sent: " + (float)total_read_len/file_len*100 + "%");
        }

        //This one copy a little bit bigger
        /*while( (bytesRead = bis.read(buffer)) != -1 ){
            total_read_len += bytesRead;
            sOut.writeBoolean(true);
            sOut.writeObject(buffer);
            System.out.println("Sent: " + (float)total_read_len/file_len*100 + "%");
        }*/

        sOut.writeBoolean(false);

        System.out.println("Done sending file!");

        //close all connection
        bis.close();
        sOut.close();
        socket.close();


    }catch(NumberFormatException nfe){

    } catch (UnknownHostException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

public static String insert(String str, char ch){
    StringBuilder strBuff = new StringBuilder(str);
    int c = 0;

    for(int i = 0 ; i < str.length() ; i++){
        if(str.charAt(i) == ch){
            strBuff.insert(i+c, ch);
            c++;
        }
    }

    return strBuff.toString();
}

}

1 个答案:

答案 0 :(得分:-1)

客户端在每次sOut.flush()操作后写sOut.write()

当您在stream中写信时,您需要flush stream,以便读者可以从stream获取数据。

相关问题