TCP プロトコルに基づく画像アップロード

JavaBeginner
オンラインで実践に進む

はじめに

このプロジェクトでは、TCP プロトコルを使用して簡単な画像アップロードアプリケーションを構築する方法を学びます。このアプリケーションは、クライアントとサーバーで構成されており、クライアントが画像をサーバーにアップロードし、サーバーが画像を受信して保存します。

👀 プレビュー

クライアントが画像をアップロードするインターフェイス

クライアントが画像をアップロードするインターフェイス

クライアントとサーバー間の画像転送

🎯 タスク

このプロジェクトでは、以下を学びます。

  • 着信するクライアント接続を待ち受け、アップロードされた画像を受信するサーバーをセットアップする方法
  • ローカル画像ファイルを読み取り、サーバーに送信するクライアントを実装する方法
  • TCP ソケットを使用してクライアントとサーバー間の通信を処理する方法
  • 画像のアップロードが成功したときにクライアントにフィードバックを提供する方法

🏆 成果

このプロジェクトを完了すると、以下のことができるようになります。

  • Java を使用してサーバー-クライアントアーキテクチャを作成する
  • クライアントとサーバー間のファイル転送に TCP ソケットを使用する
  • Java でファイル I/O 操作を処理する
  • 基本的なエラーハンドリングとフィードバックメカニズムを実装する

サーバーをセットアップする

このステップでは、アップロードされた画像を受け取るためのサーバーをセットアップする方法を学びます。

  1. コードエディタで org/labex/service/UploadService.java ファイルを開きます。

  2. main() メソッド内で、ポート 10203 で着信するクライアント接続を待ち受ける ServerSocket オブジェクトを作成します。

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.BufferedWriter;
import java.io.OutputStreamWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
        try (ServerSocket server = new ServerSocket(10203)) {
            // クライアント接続を継続的に受け付ける
            while (true) {
                // サーバーが待機する
                // 接続があればクライアントの Socket を返す
                Socket client = server.accept();
                InetAddress clientAddress = client.getInetAddress();
                // クライアントからアップロードされた画像を受け取る
                // 入力ストリーム:クライアントが送信した画像ファイルストリームを読み取る
                // 出力ストリーム:ローカル画像に書き込む
                String name = "/home/labex/project/pic/mn.jpg";

                try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(name));
                     InputStream in = client.getInputStream();
                     BufferedInputStream bis = new BufferedInputStream(in);) {

                    // クライアントからの画像ファイルストリームを読み取る
                    // ローカルファイルに書き込む
                    byte[] buffer = new byte[1024];
                    int length = -1;
                    while ((length = bis.read(buffer))!= -1) {
                        bos.write(buffer, 0, length);
                    }

                    // クライアントにメッセージを出力する
                    try (BufferedWriter writer = new BufferedWriter(
                            new OutputStreamWriter(client.getOutputStream()))) {
                        writer.write("Reception Complete");
                        writer.newLine();
                    }
                }
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
  1. サーバーはクライアント接続を継続的に受け付け、アップロードされた画像を受け取ります。受け取った画像は /home/labex/project/pic/mn.jpg ファイルに保存されます。

  2. 画像を受け取った後、サーバーは "Reception Complete" メッセージをクライアントに送信します。

クライアントを実装する

このステップでは、サーバーに画像をアップロードするためのクライアントを実装する方法を学びます。

  1. コードエディタで org/labex/client/UploadClient.java ファイルを開きます。

  2. main() メソッド内で、127.0.0.1:10203 のサーバーに接続する Socket オブジェクトを作成します。

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
        try (
            // Socket: クライアント通信のコンポーネント
            // ローカル画像を読み取り => 出力ストリーム経由でサーバーに送信
            // OutputStream: ローカル画像ファイルストリームをサーバーに送信
            // BufferedInputStream: ローカル画像を読み取る
            Socket client = new Socket("127.0.0.1", 10203);
            OutputStream out = client.getOutputStream();
            BufferedInputStream in = new BufferedInputStream(new FileInputStream(
                    "/home/labex/project/timg.jpg"))
        ) {
            // 1 回に 1024 バイトずつ読み取る
            byte[] buffer = new byte[1024];
            int length = -1;
            while ((length = in.read(buffer))!= -1) {
                // 読み取った内容を出力ストリーム経由でサーバーに送信
                out.write(buffer, 0, length);
            }
            // "出力"の一時終了 (Socket は閉じない)
            client.shutdownOutput();

            // サーバーからのフィードバックを読み取る
            try (BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()))) {
                String reply = reader.readLine();
                System.out.println(reply);
            }
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
  1. クライアントはローカル画像ファイル /home/labex/project/timg.jpg を読み取り、ソケットの出力ストリームを使ってサーバーに送信します。

  2. 画像を送信した後、クライアントはサーバーからのフィードバックメッセージを読み取り、コンソールに表示します。

  3. サーバーが "Reception Complete" メッセージを送信した場合、画像のアップロードが成功したことを意味します。

これで、サーバーとクライアントの両方の実装が完了しました。プログラムをコンパイルして実行して、画像アップロード機能をテストできます。

実行

ターミナルを開き、以下のコマンドを実行してクライアントとサーバーのプログラムをコンパイルします。

javac org/labex/client/UploadClient.java
javac org/labex/service/UploadService.java

サーバーを起動してクライアントを待ち受けます。

java org.labex.service.UploadService

別のターミナルを開いて、クライアントを起動して画像をアップロードすると、「Reception Complete」のプロンプトが表示されます。

クライアントアップロードプロンプト

java org.labex.client.UploadClient

pic フォルダに画像が含まれているかどうかを確認します。

ls pic

実行結果は以下の通りです。

画像アップロード成功プロンプト

まとめ

おめでとうございます!このプロジェクトを完了しました。LabEx でさらに多くの実験を行って、スキルを向上させましょう。

✨ 解答を確認して練習✨ 解答を確認して練習