1

ソケット接続で複数のファイルを送信したい。1 つのファイルの場合は完全に機能しますが、複数 (一度に 1 つずつ) 送信しようとすると、次のようになりますSocket Exception

java.net.SocketException: ソケットが閉じられました

一般的に、私の接続は次のように機能します。

  1. サーバーは接続を待機しています
  2. クライアントはサーバーに接続し、特定のファイル (ファイル名を含む文字列) の要求を送信します。
  3. サーバーはローカルファイルを読み取り、クライアントに送信します
  4. クライアントは別のファイルに対する別の要求を送信し、ポイント 3 に進みます。

リクエスト待ちプロシージャの実行メソッドは次のようになります。

@Override
public void run() {
    String message;
    try {
        while ((message = reader.readLine()) != null) {

            if (message.equals(REQUESTKEY)) {
                System.out.println("read files from directory and send back");
                sendStringToClient(createCodedDirContent(getFilesInDir(new File(DIR))), socket);
            } else if (message.startsWith(FILE_PREFIX)) {

                String filename = message.substring(FILE_PREFIX.length());
                try {
                    sendFile(new File(DIR + filename));
                } catch (IOException e) {
                    System.err.println("Error: Could not send File");
                    e.printStackTrace();
                }
            } else {
                System.out.println("Key unknown!");
            }
        }
    } catch (Exception ex) {

        ex.printStackTrace();
    }
}

私のsendFile()メソッドは次のようになります。

public void sendFile(File file) throws IOException {
    FileInputStream input = new FileInputStream(file);
    OutputStream socketOut = socket.getOutputStream();

    System.out.println(file.getAbsolutePath());
    int read = 0;
    while ((read = input.read()) != -1) {
        socketOut.write(read);
    }
    socketOut.flush();

    System.out.println("File successfully sent!");

    input.close();
    socketOut.close();
}

問題は にあると思いますsocketOut.close()。残念ながら、このメソッドはソケット接続も閉じます (以降の接続の問題)。しかし、このクローズを省略した場合、ファイル転送が正しく機能しません。クライアントに不完全なファイルが到着します。

この問題を回避または修正するにはどうすればよいですか? または、要求された複数のファイルを転送するより良い方法はありますか?

ありがとうございました

4

2 に答える 2

1

send file メソッドを少し書き直して、複数のファイルを送信できるようにしましたDataOutputStream。送信するすべてのファイルを送信したら、それを渡し、ストリームを閉じる必要があります。

読み取るときは、DataInputStreamand 呼び出しを使用してlong len = dis.getLong()から、ストリームからlenバイトを読み取ってから、次のファイルに対して繰り返す必要があります。開始時のファイル数を に送信すると便利な場合があります。

public void sendFile(File file, DataOutputStream dos) throws IOException {
    if(dos!=null&&file.exists()&&file.isFile())
    {
        FileInputStream input = new FileInputStream(file);
        dos.writeLong(file.getLength());
        System.out.println(file.getAbsolutePath());
        int read = 0;
        while ((read = input.read()) != -1)
            dos.writeByte(read);
        dos.flush();
        input.close();
        System.out.println("File successfully sent!");
    }
}
于 2013-08-01T17:34:30.350 に答える
0

You can define a simple protocol between client and server. Send the file length before file content. Use DataOutputStream / DataInputStream to send / read the length. Do not close the socket after each file.

于 2013-08-01T15:59:19.520 に答える