簡體   English   中英

客戶端服務器文件傳輸Java

[英]Client Server File Transfer Java

我正在嘗試使用Java編寫應用程序,這將允許我在服務器和請求文件的客戶端之間傳輸文件。 我計划使用套接字。 我的算法有點像這樣:

在服務器上:在客戶端和服務器之間創建連接。 連接后,您需要將文件發送給客戶端。 然后將文件大小發送給客戶端。 然后發送分解成幾部分的文件。

在客戶端上創建連接后,要求提供文件。 接收文件大小,然后接受數據,直到達到文件大小。 停止。

如果我在算法中某處有誤,請糾正我

這實際上不是一個“算法”問題; 您正在設計一個(簡單的)協議。 您所描述的內容聽起來很合理,但是實在太含糊了,無法實現。 你需要更具體。 例如,您需要決定一些事情:

  • 接收程序如何知道應保存到哪個文件名? 應該通過套接字發送,還是只是問用戶?
  • 文件大小如何傳輸?
    • 是字符串嗎? 如果是這樣,如何指示其長度? (使用空終止符?換行符?)
    • 它是二進制值嗎? 如果是這樣,有多大? (32位還是64位?)什么字節序?
  • “細分”是什么意思? 如果您正在寫TCP套接字,則無需擔心數據包邊界。 TCP會解決這個問題。
  • 收件人是否將任何東西發回,例如成功或失敗指示?
  • 傳輸完整個文件后會怎樣?
    • 兩端都應該假定連接必須關閉嗎?
    • 還是可以通過單個連接發送多個文件? 如果是這樣,發件人如何指示將跟隨另一個文件?

另外,您正在反向使用術語“客戶端”和“服務器”。 通常,“客戶端”是啟動與服務器連接的計算機,而“服務器”是等待客戶端連接的計算機。

您也可以在收到文件的特定部分后從服務器添加確認,這與我們在HTTP協議中的操作類似,以確保服務器上已正確接收文件。

這是我使用的方法,它使用套接字的輸入和輸出流來發送和接收文件,完成后,它將自動重新啟動服務器並從客戶端重新連接到服務器。

服務器代碼:

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

客戶代碼:

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

此方法效果很好,我將其用於服務器和客戶端文件傳輸程序,您所需要做的就是輸入服務器主機的IP地址並選擇端口號(我使用8888)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM