0

サーバーとファイルを要求するクライアントの間でファイルを転送できるようにするJavaを使用してアプリケーションを作成しようとしています。ソケットを使ってやろうと思っています。私のアルゴリズムは次のようなものです。

サーバー上:クライアントとサーバー間の接続を作成します。接続したら、クライアントに送信する必要のあるファイルを見つけます。次に、ファイルのサイズをクライアントに送信します。次に、ファイルを分割して送信します。

クライアントで接続が作成されたら、ファイルを要求します。ファイルサイズを受け取り、ファイルサイズに達するまでデータを受け入れます。止まる。

アルゴリズムのどこかが間違っている場合は修正してください

4

3 に答える 3

2

これは実際には「アルゴリズム」の質問ではありません。(単純な)プロトコルを設計しています。あなたが説明したことは合理的に聞こえますが、実装するには曖昧すぎます。より具体的にする必要があります。たとえば、決定する必要があるいくつかのこと:

  • 受信側のプログラムは、どのファイル名に保存する必要があるかをどのようにして知るのですか?それはソケットを介して送信する必要がありますか、それとも単にユーザーに尋ねる必要がありますか?
  • ファイルサイズはどのように送信されますか?
    • 文字列ですか?もしそうなら、その長さはどのように示されますか?(ヌルターミネータを使用しますか?改行を使用しますか?)
    • バイナリ値ですか?もしそうなら、どのくらいの大きさですか?(32ビットまたは64?)どのエンディアンですか?
  • 「部分的に分解された」とはどういう意味ですか?TCPソケットに書き込む場合は、パケットの境界について心配する必要はありません。TCPがそれを処理します。
  • 受信者は、成功または失敗の表示など、何かを送り返しますか?
  • ファイル全体が送信されるとどうなりますか?
    • 両端は、接続を閉じる必要があると想定する必要がありますか?
    • または、単一の接続を介して複数のファイルを送信できますか?もしそうなら、送信者は別のファイルが続くことをどのように示しますか?

また、「クライアント」と「サーバー」という用語を逆に使用しています。通常、「クライアント」はサーバーへの接続を開始するマシンであり、「サーバー」はクライアントからの接続を待機するマシンです。

于 2012-04-12T04:44:19.130 に答える
1

HTTPプロトコルの場合と同様に、ファイルの特定の部分が受信されたら、サーバーから確認応答を追加することもできます。これにより、サーバーでファイルの適切な配信が確実に受信されます。

于 2012-04-12T04:41:30.393 に答える
0

これが私が使用する方法です。ソケットの入力ストリームと出力ストリームを使用してファイルを送受信します。完了すると、サーバーが自動的に再起動し、クライアントからサーバーに再接続します。

サーバーコード:

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を使用します)。

于 2019-01-05T05:44:00.550 に答える