简体   繁体   English

如何在客户端和服务器之间传输多个文件?

[英]How to transfer multiple files between client and server?

I rewrote a simple example of file transfer code between server and client. 我重写了服务器和客户端之间文件传输代码的简单示例。

And it works. 而且有效。

But i want to make it able to transfer multiple files in a particular directory. 但我想使其能够在特定目录中传输多个文件。 User will write the file names (which sits in that particular directory) and client will download them from the server. 用户将写入文件名(位于该特定目录中),客户端将从服务器下载它们。 How can i do that? 我怎样才能做到这一点? Any ideas? 有任何想法吗? Thank you. 谢谢。

Client code: 客户代码:

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

    public class Client {

        static String hostname = "127.0.0.1";
        static int port = 4588;
        static int processedByte; 
        static byte[] theByte = new byte[1];

        static Socket client = null; 
          static InputStream inuputSt = null; 

        public static void main(String[] args) throws InterruptedException {
            System.out.println("connecting...");
            Thread.sleep(500);
            try { 
                client = new Socket(hostname, port); 
                inuputSt = client.getInputStream(); 
            } catch (IOException ex) { 
                System.out.println("connection error.");
            } 

            ByteArrayOutputStream arrayOutput = new ByteArrayOutputStream(); 

            if (inuputSt != null) { 

                FileOutputStream fileOutput = null; 
                BufferedOutputStream bufferedOutput = null; 
                try { 
                    System.out.println("downloading target file...");
                    Thread.sleep(800);
                    fileOutput = new FileOutputStream("file1_downloaded.txt"); 
                    bufferedOutput = new BufferedOutputStream(fileOutput); 
                    processedByte = inuputSt.read(theByte, 0, theByte.length); 

                    do { 
                            arrayOutput.write(theByte); 
                            processedByte = inuputSt.read(theByte); 
                    } while (processedByte != -1); 

                    bufferedOutput.write(arrayOutput.toByteArray()); 
                    bufferedOutput.flush(); 
                    bufferedOutput.close(); 
                    System.out.println("file downloaded");
                    client.close(); 
                } catch (IOException ex) { 
                    System.out.println("file transfer error."); 
                } 
            }

        }
    }

Server code: 服务器代码:

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

public class Server {
static int port = 4588;
public static void main(String[] args) {

    while (true) {
        ServerSocket server = null; 
        Socket connection = null; 
        BufferedOutputStream bufferedOutput = null; 

        try { 
            server = new ServerSocket(port); 
            connection = server.accept(); 
            bufferedOutput = new BufferedOutputStream(connection.getOutputStream()); 
        } catch (IOException ex) { 
            // Do exception handling 
        } 

        if (bufferedOutput != null) { 
            File fileToSend = new File("files\\file1.txt"); 
            byte[] mybytearray = new byte[(int) fileToSend.length()]; 

            FileInputStream fileInputSt = null; 

            try { 
                fileInputSt = new FileInputStream(fileToSend); 
            } catch (FileNotFoundException ex) { 
                // exception stuff
            } 
            BufferedInputStream bufferedInput = new BufferedInputStream(fileInputSt); 

            try { 
                bufferedInput.read(mybytearray, 0, mybytearray.length); 
                bufferedOutput.write(mybytearray, 0, mybytearray.length); 
                bufferedOutput.flush(); 
                bufferedOutput.close(); 
                connection.close(); 

                //file1.txt has been downloaded
                return; 
            } catch (IOException ex) { 
                // exception stuff
            } 
        } 
    } 
}

}

You suggest HTTP as a protocol for your clients and servers -- HTTP is a fine protocol but may be a large implementation hurdle if you want to do the whole thing yourself. 您建议将HTTP作为客户端和服务器的协议-HTTP是一种很好的协议,但是如果您想自己完成全部操作,则可能是一个很大的实现障碍。 The HTTP PUT verb can be used to upload a file, and the benefit of using HTTP in this fashion is that your client and server could communicate with other tools designed to use PUT requests. HTTP PUT动词可用于上载文件,以这种方式使用HTTP的好处是您的客户端和服务器可以与其他旨在使用PUT请求的工具进行通信。 ( PUT is less-used than other HTTP verbs, so not all HTTP tools will work; the curl(1) program does support PUT via the -T command line option. This will be a great implementation aid, should you chose HTTP.) PUT的使用少于其他HTTP动词,因此并非所有HTTP工具都可以使用; curl(1)程序确实通过-T命令行选项支持PUT 。如果您选择HTTP,这将是一个很好的实现辅助。)

There are a variety of REST Frameworks that can assist you in writing HTTP software; 有各种各样的REST框架可以帮助您编写HTTP软件。 I have heard good things about Restlet , it would be my recommended starting point. 我听说过Restlet的好消息,这是我建议的起点。

But you don't have to pick HTTP as your protocol. 但是,你没有挑HTTP作为协议。 I think you can learn a lot about networking programming if you implement your own protocol -- it will teach you a lot about API design and sockets programming in a way that would be difficult to learn by using pre-written HTTP protocol tools (and frustrating if you tried to implement HTTP in its entirety yourself). 我认为,如果您实现自己的协议,您会学到很多有关网络编程的知识-它会通过使用预写的HTTP协议工具很难学习的方式,向您学习有关API设计和套接字编程的很多知识(并且令人沮丧如果您尝试自己完全实现HTTP)。

Consider this conversation: 考虑以下对话:

client -> server: upload file named "flubber" sized 200000 bytes 客户端->服务器:上传名为“ flubber”的文件,大小为200000字节
server -> client: ok 服务器->客户端:确定
client -> server: flubber contents 客户端->服务器: Flubber目录
server -> client: ok 服务器->客户端:确定
client -> server: upload file named "blort" sized 10 bytes 客户端->服务器:上传名为“ blort”的文件,大小为10个字节
server -> client: error, file exists 服务器->客户端:错误,文件存在
... ...

You might want to add new commands to provide for hashing the file on both ends to ensure the file transfer succeeded, commands for sending specific byte ranges (either to append to an existing file or re-start a failed transfer), commands to list existing file names on the server, commands to overwrite existing files, commands to delete files from the server, and so forth. 您可能希望添加新命令以提供对文件进行哈希处理的两端,以确保文件传输成功,发送特定字节范围的命令(追加到现有文件或重新启动失败的传输),列出现有命令服务器上的文件名,覆盖现有文件的命令,从服务器上删除文件的命令等等。 The best part of writing your own protocol is you get to decide what your programs will support. 编写自己的协议的最好的部分是您可以决定程序将支持什么。 The downside is that you get to test the features you write, and testing some cases may be difficult. 缺点是您必须测试所编写的功能,并且测试某些情况可能很困难。 (Say, consider that a client may send each character of a command in a different TCP packet. Implementing the buffering to store up an entire command isn't trivial , but it is already done for you with a tool such as Restlet.) (说,考虑到客户可以在不同的TCP数据包发送命令的每一个字符,实施缓冲存储了一个完整的指令是不平凡的 ,但它已经做了你的工具如的Restlet。)

Juan's advice to use multiple TCP sessions isn't strictly necessary -- though it may be the easiest path forward for you. Juan提出的使用多个TCP会话的建议并不是绝对必要的-尽管对于您来说这可能是最简单的方法。 You'll need to add some mechanism to provide the filename to the remote peer, and that might be best done through the "control" channel (the first session running -- similar to FTP) or it might be something you send immediately before the file's contents (similar to HTTP). 您需要添加某种机制来向远程对等方提供文件名,最好通过“控制”通道(第一个会话正在运行,类似于FTP)来完成,或者它可能是在发送文件之前立即发送的。文件的内容(类似于HTTP)。

I'd like to suggest avoiding multiple connections, though -- each connection requires three times the round-trip time between systems to set up and start transferring bytes. 但我想建议避免多个连接-每个连接需要两次系统之间的往返时间来建立和开始传输字节。 This delay can be extremely annoying, especially when you're trying to transfer hundreds of small files. 这种延迟可能非常烦人,尤其是当您尝试传输数百个小文件时。 You can even spend more time setting up connections than you do actually sending data. 与实际发送数据相比,您甚至可以花费更多的时间来建立连接。

But it's your tool -- you get to design it as you wish. 但这是您的工具-您可以根据需要进行设计。 Have fun. 玩得开心。

I think you need to create a new connection for each file so in that situation you'll be able to transfer files simultaneously. 我认为您需要为每个文件创建一个新的连接,这样在这种情况下,您将能够同时传输文件。

You may have to modify your server to create a new thread (or get one from a thread pool) for each client connection so it can work with many at the same time. 您可能需要修改服务器以为每个客户端连接创建一个新线程(或从线程池中获取一个线程),以便它可以同时使用多个线程。

Then you can run the client once per file. 然后,您可以为每个文件运行一次客户端。

Cheers 干杯

Ok, can you transfer multi files making a ArrayList or List files. 好的,您可以传输构成ArrayList或List文件的多个文件吗? Getting into in the array after get out in a filesystem path. 进入文件系统路径后进入阵列。 I hope help you. 希望对您有帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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