今回は、いよいよJavaプログラミングの醍醐味の一つ、ネットワークプログラミングの世界に足を踏み入れてみましょう。特に、ネットワークプログラミングの基本中の基本であるソケット通信について、初心者の方でも理解できるようにわかりやすく解説していきます。
ネットワークプログラミングって何?
ネットワークプログラミングと聞くと、「難しそう」「専門知識が必要そう」と感じるかもしれませんね。でも安心してください。簡単に言うと、インターネットを通じてコンピュータ同士が会話するためのプログラムを作ることです。私たちが普段使っているWebブラウザやチャットアプリも、裏側ではネットワークプログラミングが動いています。
ソケットって何?
「ソケット」と聞くと、家電製品のコンセントをイメージする人もいるかもしれませんね。ネットワークの世界でのソケットも、それに似ています。
コンピュータがネットワーク上で他のコンピュータと通信するには、まるで電話をかけるように、どこかの「窓口」を通じてやり取りします。この「窓口」こそがソケット (Socket) なんです。
ソケットは、例えるなら電話機です。電話機を通じて、相手と会話しますよね。ソケットも同じように、データという「会話」をするためのインターフェースを提供してくれます。
ソケット通信の仕組み
ソケット通信には、大きく分けて2つの役割があります。
- サーバー (Server): サービスを提供する側。電話でいうと、電話がかかってくるのを待っている側です。
- クライアント (Client): サービスを利用する側。電話でいうと、電話をかける側です。
この2つがそれぞれのソケットを通じて、データの送受信を行います。
サーバー側のソケット
サーバー側は、クライアントからの接続を「待ち受ける」必要があります。これにはServerSocketというクラスを使います。
Java
import java.net.ServerSocket;
import java.net.Socket;
import java.io.IOException;
public class SimpleServer {
public static void main(String[] args) {
int port = 12345; // 任意のポート番号
try (ServerSocket serverSocket = new ServerSocket(port)) {
System.out.println("サーバーがポート " + port + " で起動しました。");
// クライアントからの接続を待機
Socket clientSocket = serverSocket.accept();
System.out.println("クライアントが接続しました: " + clientSocket.getInetAddress().getHostAddress());
// ここでクライアントとのデータ送受信の処理を行う
} catch (IOException e) {
System.err.println("サーバーエラー: " + e.getMessage());
}
}
}
このコードでは、ServerSocketを特定のポート番号(ここでは12345)で作成しています。ポート番号は、コンピュータ上でプログラムを識別するための番号だと思ってください。Webサイトのアドレスの最後に:80とか:443とか付いているのを見たことがあるかもしれません。あれがポート番号です。
serverSocket.accept()は、クライアントからの接続要求が来るまでプログラムの実行を停止(ブロック)します。接続があれば、そのクライアントとの通信に使うSocketオブジェクトを返します。
クライアント側のソケット
クライアント側は、サーバーに接続するためにSocketクラスを使います。
Java
import java.net.Socket;
import java.io.IOException;
public class SimpleClient {
public static void main(String[] args) {
String serverAddress = "localhost"; // サーバーのアドレス (今回は自分のPC)
int port = 12345; // サーバーが待ち受けているポート番号
try (Socket socket = new Socket(serverAddress, port)) {
System.out.println("サーバーに接続しました: " + serverAddress + ":" + port);
// ここでサーバーとのデータ送受信の処理を行う
} catch (IOException e) {
System.err.println("クライアントエラー: " + e.getMessage());
}
}
}
クライアントは、サーバーのアドレス(ここではlocalhost、つまり自分のコンピュータ)とポート番号を指定してSocketオブジェクトを作成します。これにより、サーバーへの接続が試みられます。
データの送受信
ソケットが確立できたら、いよいよデータの送受信です。データの送受信には、入出力ストリームを使います。JavaのI/O(Input/Output)については、前回の記事で触れた通りです。
文字列の送受信例
ここでは、サーバーがクライアントからメッセージを受け取り、そのメッセージに応答する例を見てみましょう。
サーバー側 (SimpleServer.java)
Java
import java.net.ServerSocket;
import java.net.Socket;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
public class SimpleServer {
public static void main(String[] args) {
int port = 12345;
try (ServerSocket serverSocket = new ServerSocket(port)) {
System.out.println("サーバーがポート " + port + " で起動しました。");
while (true) { // 複数のクライアントに対応するためにループ
Socket clientSocket = serverSocket.accept();
System.out.println("クライアントが接続しました: " + clientSocket.getInetAddress().getHostAddress());
// クライアントとの通信を別スレッドで行うのが一般的ですが、今回は単純化
try (
BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); // autoFlushをtrueに
) {
String clientMessage;
while ((clientMessage = in.readLine()) != null) {
System.out.println("クライアントからのメッセージ: " + clientMessage);
out.println("サーバーからの返信: " + clientMessage + " を受け取りました!"); // クライアントに返信
if (clientMessage.equalsIgnoreCase("bye")) {
break; // "bye"と入力されたら通信終了
}
}
System.out.println("クライアントとの接続を閉じます: " + clientSocket.getInetAddress().getHostAddress());
} catch (IOException e) {
System.err.println("クライアントとの通信エラー: " + e.getMessage());
} finally {
clientSocket.close(); // クライアントソケットを閉じる
}
}
} catch (IOException e) {
System.err.println("サーバーエラー: " + e.getMessage());
}
}
}
クライアント側 (SimpleClient.java)
Java
import java.net.Socket;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Scanner;
public class SimpleClient {
public static void main(String[] args) {
String serverAddress = "localhost";
int port = 12345;
try (
Socket socket = new Socket(serverAddress, port);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(), true); // autoFlushをtrueに
Scanner scanner = new Scanner(System.in) // 標準入力から読み込む
) {
System.out.println("サーバーに接続しました: " + serverAddress + ":" + port);
String userInput;
while (true) {
System.out.print("メッセージを入力してください (終了する場合は 'bye'): ");
userInput = scanner.nextLine();
out.println(userInput); // サーバーに送信
String serverResponse = in.readLine(); // サーバーからの返信を受け取る
System.out.println("サーバーからの返信: " + serverResponse);
if (userInput.equalsIgnoreCase("bye")) {
break;
}
}
} catch (IOException e) {
System.err.println("クライアントエラー: " + e.getMessage());
}
}
}
実行してみよう!
- まず、
SimpleServer.javaをコンパイルして実行します。サーバーが起動して、クライアントからの接続を待ち受ける状態になります。 - 次に、別のターミナルを開き、
SimpleClient.javaをコンパイルして実行します。クライアントがサーバーに接続し、メッセージのやり取りができるようになります。 - クライアント側で何かメッセージを入力してEnterキーを押すと、サーバーに送られ、サーバーから返信が来るのが確認できるはずです。「bye」と入力すると、クライアント側の通信が終了します。
まとめ
今回は、Javaでのネットワークプログラミングの基礎となるソケット通信について学びました。
- ソケットは、コンピュータがネットワーク上で他のコンピュータと通信するための「窓口」のようなものです。
- サーバーは
ServerSocketを使って接続を待ち受け、クライアントはSocketを使ってサーバーに接続します。 - データの送受信には、入出力ストリーム(
InputStreamやOutputStream)を使います。
これで、Javaでシンプルなネットワークアプリケーションを作成する第一歩を踏み出せましたね!次回は、このソケット通信を応用したさらに面白いテーマに挑戦してみましょう。
Javaプログラミングの学習、引き続き頑張ってくださいね!
これまでの記事はこちらから読めますよ!: ToolDocs | 様々なツールや技術情報を紹介します


コメント