Java Socket クラス
Socket(ソケット)はネットワーク通信の基本的な構成要素であり、異なるコンピュータ間でネットワークを通じてデータ交換を行うことを可能にします。
Java では、java.net.Socketクラスはネットワーク通信を実装するクライアント機能を提供します。
Socket は、2台の電話の間の接続としてイメージできます:
- 一端はクライアント(電話をかける人)
- もう一端はサーバー(電話を受ける人)
- 接続が確立されると、双方は互いに情報を送受信できます
Socket クラスの基本的な使い方
Socket 接続の作成
Socket 接続を作成するには、サーバーのアドレスとポートを指定する必要があります:
例
try {
// localhost の 8080 ポートに接続
Socket socket = new Socket("localhost", 8080);
// socket を使用して通信...
// 接続を閉じる
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
// localhost の 8080 ポートに接続
Socket socket = new Socket("localhost", 8080);
// socket を使用して通信...
// 接続を閉じる
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
主なメソッド
Socket クラスにはいくつかの重要なメソッドがあります:
| メソッド | 説明 |
|---|---|
getInputStream() |
入力ストリームを取得し、データを受信する |
getOutputStream() |
出力ストリームを取得し、データを送信する |
close() |
Socket 接続を閉じる |
isConnected() |
接続が確立されているか確認する |
setSoTimeout(int timeout) |
タイムアウト時間を設定する(ミリ秒) |
クライアント・サーバー通信の実装
クライアントの例
例
import java.io.*;
import java.net.*;
public class Client {
public static void main(String[] args) {
try {
// 1. Socket 接続を作成
Socket socket = new Socket("localhost", 12345);
// 2. 出力ストリームを取得し、サーバーにデータを送信
PrintWriter out = new PrintWriter(
socket.getOutputStream(), true);
out.println("Hello Server!");
// 3. 入力ストリームを取得し、サーバーの応答を受信
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
String response = in.readLine();
System.out.println("Server response: " + response);
// 4. 接続を閉じる
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
import java.net.*;
public class Client {
public static void main(String[] args) {
try {
// 1. Socket 接続を作成
Socket socket = new Socket("localhost", 12345);
// 2. 出力ストリームを取得し、サーバーにデータを送信
PrintWriter out = new PrintWriter(
socket.getOutputStream(), true);
out.println("Hello Server!");
// 3. 入力ストリームを取得し、サーバーの応答を受信
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
String response = in.readLine();
System.out.println("Server response: " + response);
// 4. 接続を閉じる
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
サーバー側の例
サーバー側ではServerSocketクラスを使用する必要があります:
例
import java.io.*;
import java.net.*;
public class Server {
public static void main(String[] args) {
try {
// 1. ServerSocket を作成し、指定したポートを監視
ServerSocket serverSocket = new ServerSocket(12345);
System.out.println("Server started. Waiting for client...");
// 2. クライアントの接続を待機
Socket clientSocket = serverSocket.accept();
System.out.println("Client connected.");
// 3. 入力ストリームを取得し、クライアントのメッセージを読み取る
BufferedReader in = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
String message = in.readLine();
System.out.println("Client says: " + message);
// 4. 出力ストリームを取得し、クライアントに応答を送信
PrintWriter out = new PrintWriter(
clientSocket.getOutputStream(), true);
out.println("Hello Client!");
// 5. 接続を閉じる
clientSocket.close();
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
import java.net.*;
public class Server {
public static void main(String[] args) {
try {
// 1. ServerSocket を作成し、指定したポートを監視
ServerSocket serverSocket = new ServerSocket(12345);
System.out.println("Server started. Waiting for client...");
// 2. クライアントの接続を待機
Socket clientSocket = serverSocket.accept();
System.out.println("Client connected.");
// 3. 入力ストリームを取得し、クライアントのメッセージを読み取る
BufferedReader in = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
String message = in.readLine();
System.out.println("Client says: " + message);
// 4. 出力ストリームを取得し、クライアントに応答を送信
PrintWriter out = new PrintWriter(
clientSocket.getOutputStream(), true);
out.println("Hello Client!");
// 5. 接続を閉じる
clientSocket.close();
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Socket の高度な機能
タイムアウトの設定
例
Socket socket = new Socket();
// 接続タイムアウトを5秒に設定
socket.connect(new InetSocketAddress("example.com", 80), 5000);
// 読み取りタイムアウトを3秒に設定
socket.setSoTimeout(3000);
// 接続タイムアウトを5秒に設定
socket.connect(new InetSocketAddress("example.com", 80), 5000);
// 読み取りタイムアウトを3秒に設定
socket.setSoTimeout(3000);
接続の維持
例
// TCP キープアライブ機構を有効にする
socket.setKeepAlive(true);
socket.setKeepAlive(true);
バッファサイズ
例
// 受信バッファサイズを設定(バイト)
socket.setReceiveBufferSize(8192);
// 送信バッファサイズを設定(バイト)
socket.setSendBufferSize(8192);
socket.setReceiveBufferSize(8192);
// 送信バッファサイズを設定(バイト)
socket.setSendBufferSize(8192);
よくある問題と解決策
接続が拒否される
- サーバーが実行中かどうかを確認する
- ポート番号が正しいか確認する
- ファイアウォール設定を確認する
接続タイムアウト
- ネットワーク接続を確認する
- タイムアウト時間を長くする
- サーバーアドレスが正しいか確認する
データの受信が不完全
- 双方が同じプロトコルを使用していることを確認する
- バッファサイズが十分かどうかを確認する
- 区切り文字や固定長メッセージの使用を検討する
実際の応用シーン
Socket プログラミングは実際に幅広く応用されています:
- インスタントメッセージングアプリ(微信、QQ など)
- オンラインゲーム
- リモートコントロールソフトウェア
- ファイル転送ツール
- IoTデバイス通信
ベストプラクティス
- 常に IO 例外を処理する
- try-with-resources を使用してリソースの解放を保証する
- 重要な操作には適切なタイムアウトを設定する
- 複数の接続を処理するためにスレッドプールの使用を検討する
- 明確な通信プロトコルを設計する