简体   繁体   English

客户端服务器文件传输Java

[英]Client Server File Transfer Java

I am trying to write an application using Java that will allow me to transfer files between a server and a client that requests the file. 我正在尝试使用Java编写应用程序,这将允许我在服务器和请求文件的客户端之间传输文件。 I plan to do it using sockets. 我计划使用套接字。 My algorithm is somewhat like this: 我的算法有点像这样:

On Server: Create the connection between client and server. 在服务器上:在客户端和服务器之间创建连接。 Once connected find the file u need to send to client. 连接后,您需要将文件发送给客户端。 Then send the size of file to client. 然后将文件大小发送给客户端。 Then send file broken down in parts. 然后发送分解成几部分的文件。

On Client After connection is created, ask for the file. 在客户端上创建连接后,要求提供文件。 Receive the file size, then accept data till u reach file size. 接收文件大小,然后接受数据,直到达到文件大小。 Stop. 停止。

Please correct me if i am wrong somewhere in the algorithm 如果我在算法中某处有误,请纠正我

This isn't really an "algorithm" question; 这实际上不是一个“算法”问题; you're designing a (simple) protocol. 您正在设计一个(简单的)协议。 What you've described sounds reasonable, but it's too vague to implement. 您所描述的内容听起来很合理,但是实在太含糊了,无法实现。 You need to be more specific. 你需要更具体。 For example, some things you need to decide: 例如,您需要决定一些事情:

  • How does the receiving program know what filename it should save to? 接收程序如何知道应保存到哪个文件名? Should that be sent through the socket, or should it just ask the user? 应该通过套接字发送,还是只是问用户?
  • How is the file size transmitted? 文件大小如何传输?
    • Is it a character string? 是字符串吗? If so, how is its length indicated? 如果是这样,如何指示其长度? (With a null terminator? A newline?) (使用空终止符?换行符?)
    • Is it a binary value? 它是二进制值吗? If so, how big? 如果是这样,有多大? (32 bits or 64?) What endianness? (32位还是64位?)什么字节序?
  • What does "broken down in parts" mean? “细分”是什么意思? If you're writing to a TCP socket, you don't need to worry about packet boundaries; 如果您正在写TCP套接字,则无需担心数据包边界。 TCP takes care of that. TCP会解决这个问题。
  • Does the recipient send anything back, like a success or failure indication? 收件人是否将任何东西发回,例如成功或失败指示?
  • What happens when the whole file has been transmitted? 传输完整个文件后会怎样?
    • Should both ends assume that the connection must be closed? 两端都应该假定连接必须关闭吗?
    • Or can you send multiple files through a single connection? 还是可以通过单个连接发送多个文件? If so, how does the sender indicate that another file will follow? 如果是这样,发件人如何指示将跟随另一个文件?

Also, you're using the terms "client" and "server" backward. 另外,您正在反向使用术语“客户端”和“服务器”。 Typically the "client" is the machine that initiates a connection to a server, and the "server" is the machine that waits for connections from clients. 通常,“客户端”是启动与服务器连接的计算机,而“服务器”是等待客户端连接的计算机。

您也可以在收到文件的特定部分后从服务器添加确认,这与我们在HTTP协议中的操作类似,以确保服务器上已正确接收文件。

Here is the method that I use, it uses the socket's input and output streams to send and receive the files, and when it's done, it will automatically restart the server and reconnect to it from the client. 这是我使用的方法,它使用套接字的输入和输出流来发送和接收文件,完成后,它将自动重新启动服务器并从客户端重新连接到服务器。

Server Code: 服务器代码:

package app.server;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Functions 
{
    private static ServerSocket server;
    private static Socket socket;

    public static void startServer(int port)
    {   
        try 
        {
            server = new ServerSocket(port);
            socket = server.accept();
        }
        catch (IOException ex) 
        {
            Logger.getLogger(Functions.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    private static void restartServer()
    {
        new Thread()
        {
            @Override
            public void run()
            {
                try 
                {
                    socket = server.accept();
                } 
                catch (IOException ex) 
                {
                    Logger.getLogger(Functions.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }.start();
    }

    public static void sendFile(String inputFilePath)
    {
        FileInputStream fis;
        BufferedInputStream bis;
        OutputStream os;
        BufferedOutputStream bos;
        try 
        {
            File input = new File(inputFilePath);
            fis = new FileInputStream(input);
            bis = new BufferedInputStream(fis);
            os = socket.getOutputStream();
            bos = new BufferedOutputStream(os);
            byte[] buffer = new byte[1024];
            int data;
            while(true)
            {
                data = bis.read(buffer);
                if(data != -1)
                {
                    bos.write(buffer, 0, 1024);
                }
                else
                {
                    bis.close();
                    bos.close();
                    break;
                }
            }
        } 
        catch (FileNotFoundException ex) 
        {
            Logger.getLogger(Functions.class.getName()).log(Level.SEVERE, null, ex);
        } 
        catch (IOException ex) 
        {
            Logger.getLogger(Functions.class.getName()).log(Level.SEVERE, null, ex);
        }
        restartServer();
    }
}

Client Code: 客户代码:

package app.client;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Functions 
{
    private static Socket socket;
    private static String hostName;
    private static int portNumber;

    public static void connectToServer(String host, int port)
    {
        new Thread()
        {
            @Override
            public void run()
            {
                try 
                {
                    hostName = host;
                    portNumber = port;
                    socket = new Socket(host, port);
                } 
                catch (IOException ex) 
                {
                    Logger.getLogger(Functions.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }.start();
    }

    private static void reconnectToServer()
    {
        try 
        {
            socket = new Socket(hostName, portNumber);
        } 
        catch (IOException ex) 
        {
            Logger.getLogger(Functions.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public static void receiveFile(String outputFilePath)
    {
        InputStream is;
        BufferedInputStream bis;
        FileOutputStream fos;
        BufferedOutputStream bos;
        try 
        {
            File output = new File(outputFilePath);
            is = socket.getInputStream();
            bis = new BufferedInputStream(is);
            fos = new FileOutputStream(output);
            bos = new BufferedOutputStream(fos);
            byte[] buffer = new byte[1024];
            int data;
            while(true)
            {
                data = bis.read(buffer);
                if(data != -1)
                {
                    bos.write(buffer, 0, 1024);
                }
                else
                {
                    bis.close();
                    bos.close();
                    break;
                }
            }
        } 
        catch (IOException ex) 
        {
            Logger.getLogger(Functions.class.getName()).log(Level.SEVERE, null, ex);
        }
        reconnectToServer();
    }
}

This method works very well, I use it for my server and client file transfer program, all you need to do is enter the Server Host's IP address and choose a port number (I use 8888). 此方法效果很好,我将其用于服务器和客户端文件传输程序,您所需要做的就是输入服务器主机的IP地址并选择端口号(我使用8888)。

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

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