4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Javaで作る簡易ソケット通信プログラムを解説

4
Posted at

対象読者

  • Javaでサーバ↔クライアント間の通信をどうやるか見てみたい方
  • BufferReaderやStreamReaderについて何となくの理解をしている方
  • Javaを学び始めた初心者の方

できること

  • Java標準のServerSocket/Socketだけで、1行メッセージをやり取りするミニサーバ・クライアントを作る
  • InputStream→InputStreamReader→BufferedReaderのラップ構造を理解し、BufferdReaderインスタンス.readLine()で行単位の受信ができるようになる
  • OutputStream→PrintWriterでprintln()送信&オートフラッシュの挙動を押さえる

全体の動作イメージ

  1. サーバが指定ポートで待機(例: 8080)。
  2. クライアントが接続し、1行メッセージを送信。
  3. サーバは受け取った行を大文字化して返信。
  4. 双方ともソケットを閉じて終了。

コード実装例

Server.java
// サーバ(Server.java)
  import java.io.BufferedReader;
  import java.io.IOException;
  import java.io.InputStreamReader;
  import java.io.PrintWriter;
  import java.net.ServerSocket;
  import java.net.Socket;
  import java.nio.charset.StandardCharsets;

  public class Server {
      public static void main(String[] args) {
          int port = 8080; // テスト用途。80は管理者権限が必要なことが多い
          try (ServerSocket serverSocket = new ServerSocket(port)) {
              System.out.println("サーバ起動: port=" + port);
              while (true) {
                  try (Socket socket = serverSocket.accept();
                       BufferedReader in = new BufferedReader(
                           new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8));
                       PrintWriter out = new PrintWriter(socket.getOutputStream(), true)) {

                      System.out.println("クライアント接続: " + socket.getInetAddress());

                      String line = in.readLine(); // 1行受信(改行は除去)。切断ならnull
                      System.out.println("受信: " + line);

                      if (line != null) {
                          out.println("サーバからの応答: " + line.toUpperCase());
                      }
                  } catch (IOException e) {
                      // 個別接続の例外はログに流してループ継続
                      e.printStackTrace();
                  }
              }
          } catch (IOException e) {
              // サーバソケット生成やbind失敗
              e.printStackTrace();
          }
      }
  }
Client.java
  // クライアント(Client.java)
  import java.io.BufferedReader;
  import java.io.IOException;
  import java.io.InputStreamReader;
  import java.io.PrintWriter;
  import java.net.Socket;
  import java.nio.charset.StandardCharsets;

  public class Client {
      public static void main(String[] args) {
          String host = "localhost";
          int port = 8080;

          try (Socket socket = new Socket(host, port);
               BufferedReader in = new BufferedReader(
                   new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8));
               PrintWriter out = new PrintWriter(socket.getOutputStream(), true)) {

              String message = "hello, socket!";
              System.out.println("送信: " + message);
              out.println(message); // 改行付きで送信(printlnなのでオートフラッシュで即送出)

              String response = in.readLine(); // 1行受信
              System.out.println("受信: " + response);
          } catch (IOException e) {
              e.printStackTrace();
          }
      }
  }

細かい部分の説明(行ごとに噛み砕く)

受信側(サーバ/クライアント共通)

inと命名しているBufferdReaderインスタンスの深掘りです

  • socket.getInputStream()
    • ソケットの「生のバイト受信口」を取る
    • まだ文字ではなくバイト列でデータを受け取ります
  • new InputStreamReader(..., StandardCharsets.UTF_8)
    • バイト列をUTF-8で「文字」にデコードするフィルター
    • ここで初めて文字化します
  • new BufferedReader(...)
    • まとめ読み+内部バッファを持ち、改行を探してreadLine()(受け取った文字列を一行ずつ読むためのメソッド)を使えるようにするラッパー
    • バッファとは「届いたデータを一時的に溜めるメモリ領域」。改行が来るまで貯め、見つかったら1行として返す

送信側

outと命名しているPrintWriterインスタンスの深掘りです

  • socket.getOutputStream()
    • ソケットの「生のバイト列送信口」
  • new PrintWriter(..., true)
    • 文字列を書き込むラッパー
    • 第2引数trueでオートフラッシュON
    • printlnを呼ぶたびにバッファが即フラッシュされ、ネットワークに流れる。
    • println("...")は末尾に改行を付けて送るので、行単位でのやり取りに便利。

メインの流れ(サーバ側)

  1. ServerSocket serverSocket = new ServerSocket(port);
    • ポートにbindして待機。
  2. Socket socket = serverSocket.accept();
    • クライアントからの接続を受け入れ、個別のソケットを取得。
  3. 入出力ストリームをラップして、in.readLine()で1行受信、out.println(...)で1行応答。
  4. try-with-resourcesでSocket/Reader/Writerを自動クローズ。
4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?