Java サンプル - Socket を使用したマルチスレッドサーバープログラムの実装
Java では、マルチスレッドサーバープログラムを実装するには、次を使用できます。ServerSocketクライアント接続をリッスンし、新しいクライアント接続があるたびに新しいスレッドを起動してその接続を処理します。以下は、Java Socket を使用してマルチスレッドサーバープログラムを実装する方法を示すサンプルコードです。
サーバー側コード
まず、指定されたポートをリッスンし、各クライアント接続に対して新しいスレッドを起動して通信を処理するサーバープログラムを作成します。
MultiThreadedServer.java ファイル
import java.io.*;
import java.net.*;
public class MultiThreadedServer {
public static void main(String[] args) {
int port = 12345; //サーバーポートの定義
try (ServerSocket serverSocket = new ServerSocket(port)) {
System.out.println("サーバーが起動しました。クライアント接続を待機しています...");
while (true) {
Socket clientSocket = serverSocket.accept(); //クライアント接続を受け付ける
System.out.println("クライアントが接続しました:" + clientSocket.getInetAddress().getHostAddress());
//各クライアント接続に対して新しいスレッドを起動する
ClientHandler clientHandler = new ClientHandler(clientSocket);
new Thread(clientHandler).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
class ClientHandler implements Runnable {
private Socket clientSocket;
public ClientHandler(Socket socket) {
this.clientSocket = socket;
}
@Override
public void run() {
try (
InputStream input = clientSocket.getInputStream();
OutputStream output = clientSocket.getOutputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
PrintWriter writer = new PrintWriter(output, true)
) {
String clientMessage;
while ((clientMessage = reader.readLine()) != null) {
System.out.println("クライアントからメッセージを受信:" + clientMessage);
writer.println("サーバーの応答:" + clientMessage); //応答メッセージをクライアントに送信する
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
クライアント側コード
クライアントコードはサーバーに接続してメッセージを送信するために使用されます。複数のクライアントを作成して、サーバーのマルチスレッド処理能力をテストできます。
Client.java ファイルコード:
import java.io.*;
import java.net.*;
public class Client {
public static void main(String[] args) {
String serverAddress = "localhost";
int port = 12345; // サーバーポート
try (Socket socket = new Socket(serverAddress, port)) {
System.out.println(サーバーに接続しました);
OutputStream output = socket.getOutputStream();
PrintWriter writer = new PrintWriter(output, true);
InputStream input = socket.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
BufferedReader consoleReader = new BufferedReader(new InputStreamReader(System.in));
String userInput;
while ((userInput = consoleReader.readLine()) != null) {
writer.println(userInput);
String serverResponse = reader.readLine();
System.out.println(サーバーの応答: + serverResponse);
}
} catch (UnknownHostException e) {
System.err.println(不明なホスト: + serverAddress);
e.printStackTrace();
} catch (IOException e) {
System.err.println(I/O 接続を取得できません: + serverAddress);
e.printStackTrace();
}
}
}
import java.net.*;
public class Client {
public static void main(String[] args) {
String serverAddress = "localhost";
int port = 12345; // サーバーポート
try (Socket socket = new Socket(serverAddress, port)) {
System.out.println(サーバーに接続しました);
OutputStream output = socket.getOutputStream();
PrintWriter writer = new PrintWriter(output, true);
InputStream input = socket.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
BufferedReader consoleReader = new BufferedReader(new InputStreamReader(System.in));
String userInput;
while ((userInput = consoleReader.readLine()) != null) {
writer.println(userInput);
String serverResponse = reader.readLine();
System.out.println(サーバーの応答: + serverResponse);
}
} catch (UnknownHostException e) {
System.err.println(不明なホスト: + serverAddress);
e.printStackTrace();
} catch (IOException e) {
System.err.println(I/O 接続を取得できません: + serverAddress);
e.printStackTrace();
}
}
}
実行手順
-
サーバー側を実行:
- コンパイルして実行
MultiThreadedServerクラス。 - サーバーが起動し、指定されたポートでクライアント接続を待ち受けます。
- コンパイルして実行
-
クライアントを実行:
- 複数の...をコンパイルして実行
Clientクラスインスタンスで、複数のクライアントがサーバーに接続することをシミュレートします。 - クライアントのコンソールにメッセージを入力すると、クライアントはメッセージをサーバーに送信し、サーバーは同じメッセージを返信します。
- 複数の...をコンパイルして実行
説明
ServerSocket: クライアント接続を待ち受けるサーバー側のソケット。Socket: クライアントとサーバー間の通信チャネル。ClientHandler: 各クライアント接続を処理するスレッドクラス。BufferedReaderとPrintWriter: データストリームの読み書きに使用されます。
この実装方法により、サーバーは複数のクライアント接続を同時に処理でき、1つのクライアントの長時間の操作によって他のクライアントの要求がブロックされることはありません。
コードのコンパイル
ターミナルまたはコマンドプロンプトを開き、上記の Java ファイルが保存されているディレクトリに移動して、コードをコンパイルします:
javac MultiThreadedServer.java Client.java
コンパイルが完了したら、まずサーバープログラムを実行します。サーバーが起動し、ポート 12345 のリッスンを開始します。
java MultiThreadedServer
サーバーの出力は次のようになります:
サーバーが起動しました。クライアントの接続を待っています...
別のターミナルまたはコマンドプロンプトウィンドウを開き、クライアントプログラムを実行します。複数のクライアントインスタンスを実行して、マルチスレッド処理をテストできます。
java Client
クライアントの出力は次のようになります:
サーバーに接続しました
次に、クライアントコンソールにメッセージを入力できます。例:
Hello Server
サーバーは次のように応答します:
服务器回应: Hello Server
サーバー側の出力には次のように表示されます:
客户端已连接: 127.0.0.1 收到客户端消息: Hello Serverその他の拡張