如何使用Java Socket实现客户端和服务器之间的文件传输

35

我已经实现了简单的TCP服务器和TCP客户端类,可以发送客户端到服务器的消息,并且消息将在服务器端转换为大写。但是,如何实现从服务器向客户端传输文件以及从客户端向服务器上传文件?以下代码是我得到的:

TCPClient.java

        import java.io.*;
        import java.net.*;
        import java.util.Scanner;

 class TCPClient {

public static void main(String args[]) throws Exception {
        int filesize=6022386;
        int bytesRead;
        int current = 0;
    String ipAdd="";
    int portNum=0;
    boolean goes=false;
    if(goes==false){
    System.out.println("please input the ip address of the file server");
    Scanner scan=new Scanner(System.in);
    ipAdd=scan.nextLine();
    System.out.println("please input the port number of the file server");
    Scanner scan1=new Scanner(System.in);
    portNum=scan1.nextInt();
    goes=true;
    }
    System.out.println("input done");
    int timeCount=1;
    while(goes==true){
    //System.out.println("connection establishing");

    String sentence="";
    String modifiedSentence;

    BufferedReader inFromUser = new BufferedReader(new InputStreamReader(
            System.in));

    Socket clientSocket = new Socket(ipAdd, portNum);
    //System.out.println("connecting");
    //System.out.println(timeCount);
    if(timeCount==1){
    sentence="set";
    //System.out.println(sentence);


    }
    if(timeCount!=1)
        sentence = inFromUser.readLine();
            if(sentence.equals("close"))
                clientSocket.close();
            if(sentence.equals("download"))
            {
                byte [] mybytearray  = new byte [filesize];
                InputStream is = clientSocket.getInputStream();
                FileOutputStream fos = new FileOutputStream("C:\\users\\cguo\\kk.lsp");
                BufferedOutputStream bos = new BufferedOutputStream(fos);
                bytesRead = is.read(mybytearray,0,mybytearray.length);
                current = bytesRead;
                do {
   bytesRead =
      is.read(mybytearray, current, (mybytearray.length-current));
   if(bytesRead >= 0) current += bytesRead;
} while(bytesRead > -1);

bos.write(mybytearray, 0 , current);
bos.flush();
long end = System.currentTimeMillis();
//System.out.println(end-start);
bos.close();
clientSocket.close();
            }
           // if(sentence.equals("send"))
               // clientSocket.
    timeCount--;
    //System.out.println("connecting1");
    DataOutputStream outToServer = new DataOutputStream(clientSocket
            .getOutputStream());

    BufferedReader inFromServer = new BufferedReader(new InputStreamReader(
            clientSocket.getInputStream()));


    //System.out.println("connecting2");
    //System.out.println(sentence);
    outToServer.writeBytes(sentence + "\n");

    modifiedSentence = inFromServer.readLine();

    System.out.println("FROM SERVER:" + modifiedSentence);

    clientSocket.close();

}
}

          import java.io.*;
       import java.net.*;

     class TCPServer {
public static void main(String args[]) throws Exception {

    Socket s = null;

    int firsttime=1;


    while (true) {
        String clientSentence;
    String capitalizedSentence="";

        ServerSocket welcomeSocket = new ServerSocket(3248);
        Socket connectionSocket = welcomeSocket.accept();

             //Socket sock = welcomeSocket.accept();


        BufferedReader inFromClient = new BufferedReader(
                new InputStreamReader(connectionSocket.getInputStream()));

        DataOutputStream outToClient = new DataOutputStream(
                connectionSocket.getOutputStream());

        clientSentence = inFromClient.readLine();
        //System.out.println(clientSentence);
                    if(clientSentence.equals("download"))
                    {
                         File myFile = new File ("C:\\Users\\cguo\\11.lsp");
  byte [] mybytearray  = new byte [(int)myFile.length()];
  FileInputStream fis = new FileInputStream(myFile);
  BufferedInputStream bis = new BufferedInputStream(fis);
  bis.read(mybytearray,0,mybytearray.length);
  OutputStream os = connectionSocket.getOutputStream();
  System.out.println("Sending...");
  os.write(mybytearray,0,mybytearray.length);
  os.flush();
  connectionSocket.close();
                    }
        if(clientSentence.equals("set"))
            {outToClient.writeBytes("connection is ");
            System.out.println("running here");
            //welcomeSocket.close();
             //outToClient.writeBytes(capitalizedSentence);
            }



        capitalizedSentence = clientSentence.toUpperCase() + "\n";


    //if(!clientSentence.equals("quit"))
           outToClient.writeBytes(capitalizedSentence+"enter the message or command: ");


        System.out.println("passed");
        //outToClient.writeBytes("enter the message or command: ");
        welcomeSocket.close();
    System.out.println("connection terminated");
    }
}

那么,TCPServer.java将首先被执行,然后执行TCPClient.java,在TCPServer.java中尝试使用if语句来测试用户的输入内容,现在我真的想实现如何从两端传输文件(下载和上传)。谢谢。


完整的示例在这里 https://github.com/hardeepvicky/Java-FileTransfer - Hardeep Singh
1个回答

26

粗略地阅读源代码,似乎你已经接近成功了。以下链接应该会有所帮助(我曾经做过类似的FTP操作)。对于从服务器发送到客户端的文件,你需要一个文件实例和一个字节数组。然后将文件读入字节数组中,并将字节数组写入OutputStream,这对应着客户端侧的InputStream。

http://www.rgagnon.com/javadetails/java-0542.html

编辑:这里是一个能工作的超简单文件发送和接收程序,请确保你理解了代码在两端的操作。

package filesendtest;

import java.io.*;
import java.net.*;

class TCPServer {

    private final static String fileToSend = "C:\\test1.pdf";

    public static void main(String args[]) {

        while (true) {
            ServerSocket welcomeSocket = null;
            Socket connectionSocket = null;
            BufferedOutputStream outToClient = null;

            try {
                welcomeSocket = new ServerSocket(3248);
                connectionSocket = welcomeSocket.accept();
                outToClient = new BufferedOutputStream(connectionSocket.getOutputStream());
            } catch (IOException ex) {
                // Do exception handling
            }

            if (outToClient != null) {
                File myFile = new File( fileToSend );
                byte[] mybytearray = new byte[(int) myFile.length()];

                FileInputStream fis = null;

                try {
                    fis = new FileInputStream(myFile);
                } catch (FileNotFoundException ex) {
                    // Do exception handling
                }
                BufferedInputStream bis = new BufferedInputStream(fis);

                try {
                    bis.read(mybytearray, 0, mybytearray.length);
                    outToClient.write(mybytearray, 0, mybytearray.length);
                    outToClient.flush();
                    outToClient.close();
                    connectionSocket.close();

                    // File sent, exit the main method
                    return;
                } catch (IOException ex) {
                    // Do exception handling
                }
            }
        }
    }
}

package filesendtest;

import java.io.*;
import java.io.ByteArrayOutputStream;
import java.net.*;

class TCPClient {

    private final static String serverIP = "127.0.0.1";
    private final static int serverPort = 3248;
    private final static String fileOutput = "C:\\testout.pdf";

    public static void main(String args[]) {
        byte[] aByte = new byte[1];
        int bytesRead;

        Socket clientSocket = null;
        InputStream is = null;

        try {
            clientSocket = new Socket( serverIP , serverPort );
            is = clientSocket.getInputStream();
        } catch (IOException ex) {
            // Do exception handling
        }

        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        if (is != null) {

            FileOutputStream fos = null;
            BufferedOutputStream bos = null;
            try {
                fos = new FileOutputStream( fileOutput );
                bos = new BufferedOutputStream(fos);
                bytesRead = is.read(aByte, 0, aByte.length);

                do {
                        baos.write(aByte);
                        bytesRead = is.read(aByte);
                } while (bytesRead != -1);

                bos.write(baos.toByteArray());
                bos.flush();
                bos.close();
                clientSocket.close();
            } catch (IOException ex) {
                // Do exception handling
            }
        }
    }
}

相关问题

如何处理Java中长度未知的字节数组

编辑:在传输小文件之前和之后可以使用以下方法来指纹识别(如果需要,可使用SHA):

public static String md5String(File file) {
    try {
        InputStream fin = new FileInputStream(file);
        java.security.MessageDigest md5er = MessageDigest.getInstance("MD5");
        byte[] buffer = new byte[1024];
        int read;
        do {
            read = fin.read(buffer);
            if (read > 0) {
                md5er.update(buffer, 0, read);
            }
        } while (read != -1);
        fin.close();
        byte[] digest = md5er.digest();
        if (digest == null) {
            return null;
        }
        String strDigest = "0x";
        for (int i = 0; i < digest.length; i++) {
            strDigest += Integer.toString((digest[i] & 0xff)
                    + 0x100, 16).substring(1).toUpperCase();
        }
        return strDigest;
    } catch (Exception e) {
        return null;
    }
}

这段代码存在太多基本问题。读取结果被忽略;完全没有必要使用ByteArrayOutPutStreams;效率低下的单字节复制循环;... -1 - user207421
随意添加:Stackoverflow也是一个协作空间。 - James P.
谢谢James提供的示例,非常有帮助。 - Neelam Singh
我们如何更改代码以反转这个过程。客户端发送文件给服务器进行存储。 - Zee Ken
太棒了,非常感谢你,詹姆斯。 - Pavel
显示剩余15条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接