Webサイト制作コースのお申し込みはこちら

システム開発の現場では、ソケット通信を用いて他のシステムと情報を連携することがあります。スマホゲームやメールや SNS など、現代の IT に通信処理は欠かせないものとなっています。この記事では、Java でソケット通信を実装する方法について解説していきます。

ソケット通信とは

ソケット通信とは、異なる機器やアプリケーションが、相互に通信を行うための仕組みで、OSI 参照モデルでいうとトランスポート層に位置付けられているプロトコルです。

普段よく使う HTTP やメールなどの通信は、OSI 参照モデルのアプリケーション層で行われており、これらは下位レイアのソケット通信に通信フォーマットなどのプロトコルが定められたものです。

このように、ソケット通信は TCPプロトコルを用いた通信全般のことを指し、HTTP やメールなどの通信を行うための土台になっています。

Javaでソケット通信する用途とは?

Java で HTTP やメール、FTP通信を行う時は、アプリケーション層レベルでのクラスが用意されているため、下位のレイアにあたるソケット通信の部分を意識する必要はなく、基本的には Java SDKに用意されているクラスを使うのが一般的です。

ソケット通信を利用するシーンとしては、例えば製造業で使用する製作機械などは、独自の通信プロトコルを使って TCP でデータのやり取りをすることが多いため、そういった時に Java でソケット通信の処理を行うことや、スマホアプリなどを初めとするゲームなどでも、できるだけ通信量を減らすために、あえて HTTP などのプロトコルを用いずに、独自の通信プロトコルによって情報量をコンパクトするためソケット通信を使用したりします。

ソケット通信を実装してみよう

それでは、 Java でソケット通信を行うための具体的なサンプルコードを作っていきましょう。ソケット通信は、特定の TCP ポートを解放し、そのポートへの接続を待ち受けるサーバー側の処理と、そこに接続を行うクライアントの処理があります。

サーバー側の実装

まずは、サーバー側の実装をしていきます。サーバー側の処理の流れは大まかに次のようになります。

  1. サーバーソケットを作成
  2. クライアントからの接続待機(accept)
  3. クライアントとのメッセージのやりとり
  4. 次のクライアントからの接続を待ち受け

上の流れを踏まえて、サンプルコードを見てみましょう。

今回、「3. クライアントとのメッセージのやりとり」の部分は、クライアントから送信されたメッセージをコンソールに出力し、exit というコマンドが送信されるまで、応答メッセージに Please input: という文字を返す単純な作りになっています。

import java.io.*;
import java.net.*;

public class Main {
  public static void main(String[] args) {

    // -----------------------------------------
    // 1.TCPポートを指定してサーバソケットを作成
    // -----------------------------------------
    try (ServerSocket server = new ServerSocket(10000)) {

      while (true) {
        try {
          // -----------------------------------------
          // 2.クライアントからの接続を待ち受け(accept)
          // -----------------------------------------
          Socket sc = server.accept();
          System.out.println("クライアントからの接続がありました。");

          BufferedReader reader = null;
          PrintWriter writer = null;

          // -----------------------------------------
          // 3.クライアントからの接続ごとにスレッドで通信処理を実行
          // -----------------------------------------
          try {
            // クライアントからの受取用
            reader = new BufferedReader(new InputStreamReader(sc.getInputStream()));
            // サーバーからクライアントへの送信用
            writer = new PrintWriter(sc.getOutputStream(), true);

            // クライアントから「exit」が入力されるまで無限ループ
            String line = null;
            while (true) {
              // クライアントから送信されたメッセージを取得
              line = reader.readLine();

              if (line.equals("exit")) {
                break;
              }

              System.out.println("クライアントからのメッセージ=" + line);
              writer.println("Please input:");              
            }

          } catch (Exception e) {
            e.printStackTrace();
          } finally {
            // リソースの解放
            if (reader != null)
              reader.close();
            if (writer != null)
              writer.close();
            if (sc != null)
              sc.close();
          }

        } catch (Exception ex) {
          ex.printStackTrace();
          break;
        }
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}
ポテパンダの一言メモ

上のサンプルコードは、処理の流れを分かりやすくするため、クライアントとのメッセージのやりとりの部分をメインのスレッド上で行っていますが、通常は複数のクライアントからの接続を待ち受けて、同時に処理を行う必要があるため、クライアントとのやりとり部分はスレッド化します。

クライアントの実装

次に、クライアント側の実装をしていきましょう。クライアントは、サーバー側で解放した TCP ポート(今回は 10000)に対して接続を行い、メッセージの送信を行います。

今回は、キーワードで入力された文字をサーバー側に送信し、exit が入力されるまで処理を繰り返すクライアントを作成します。

import java.io.*;
import java.net.*;

public class SocketClient {
  public static void main(String[] args) {
    // クライアントソケットを生成
    try (Socket socket = new Socket("localhost", 10000);
        PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);
        BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        // キーボード入力用のリーダーの作成
        BufferedReader keyboard = new BufferedReader(new InputStreamReader(System.in))) {
      // 「exit」を入力するまで繰り返し
      while (true) {
        System.out.print("IN>");
        String input = keyboard.readLine();
        writer.println(input);
        if (input.equals("exit")) {
          break;
        }
        System.out.println("[サーバーからの応答]" + reader.readLine());
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}

まとめ

今回は、HTTP や FTP などのアプリケーション層よりも下位のレイアで通信を行う、ソケット通信について解説してきました。

HTTP通信が主流になった昨今においては、ソケット通信をあまり使う機会が少なくなったかもしれませんが、通信データの削減や、相手からの応答を確実に検知したい時など、今でもソケット通信を利用するケースは残っているため、覚えておいて損はないでしょう。

【関連記事】
Javaのキューとスタックのデータ構造をサンプルコードを見ながら理解する

エンジニアになりたい人に選ばれるプログラミングスクール「ポテパンキャンプ 」

ポテパンキャンプは卒業生の多くがWebエンジニアとして活躍している実践型プログラミングスクールです。 1000名以上が受講しており、その多くが上場企業、ベンチャー企業のWebエンジニアとして活躍しています。

基礎的な学習だけで満足せず、実際にプログラミングを覚えて実践で使えるレベルまで学習したいという方に人気です。 プログラミングを学習し実践で使うには様々な要素が必要です。

それがマルっと詰まっているポテパンキャンプでプログラミングを学習してみませんか?

卒業生の多くがWebエンジニアとして活躍

卒業生の多くがWeb企業で活躍しております。
実践的なカリキュラムをこなしているからこそ現場でも戦力となっております。
活躍する卒業生のインタビューもございますので是非御覧ください。

経験豊富なエンジニア陣が直接指導

実践的なカリキュラムと経験豊富なエンジニアが直接指導にあたります。
有名企業のエンジニアも多数在籍し品質高いWebアプリケーションを作れるようサポートします。

満足度高くコスパの高いプログラミングスクール「ポテパンキャンプ」

運営する株式会社ポテパンは10,000人以上のエンジニアのキャリアサポートを行ってきております。
そのノウハウを活かして実践的なカリキュラムを随時アップデートしております。

代表の宮崎もプログラミングを覚えサイトを作りポテパンを創業しました。
本気でプログラミングを身につけたいという方にコスパ良く受講していただきたいと思っておりますので、気になる方はぜひスクール詳細をのぞいてくださいませ。