Javaのjava.netパッケージを利用することで、ネットワークを介したデータの送受信を容易に実装できます。ここでは、信頼性の高い通信を実現するTCPと、高速性を重視するUDPの2つのプロトコルについて、具体的な実装方法を解説します。
TCPプロトコルによる双方向通信
TCP(Transmission Control Protocol)は、接続を確立してから通信を行うコネクション型のプロトコルです。サーバーとクライアントの双方が、ソケットを通じてデータのストリームをやり取りします。
1. サーバーとクライアントの基盤構築
サーバー側はServerSocketを使用して特定のポートで待機し、クライアント側はSocketを使用して接続を試みます。
// サーバー側の待機処理
ServerSocket hostServer = new ServerSocket(9000);
System.out.println("クライアントからの接続を待機しています...");
Socket clientConnection = hostServer.accept(); // 接続されるまでスレッドをブロック
System.out.println("接続が確立されました。");
// クライアント側の接続処理
Socket communicationSocket = new Socket("127.0.0.1", 9000);
2. データの送受信フロー
接続後の通信には、バイト単位で処理する方法と、高レベルなストリームを利用する方法の2種類があります。
低レベルストリーム(OutputStream/InputStream)
単純なバイト配列をそのまま操作する場合に適しています。
// 送信処理(クライアント側など)
OutputStream os = communicationSocket.getOutputStream();
String request = "Hello Server";
os.write(request.getBytes());
// 受信処理(サーバー側など)
InputStream is = clientConnection.getInputStream();
byte[] buffer = new byte[512];
int length = is.read(buffer);
String message = new String(buffer, 0, length);
System.out.println("受信データ: " + message);
高レベルストリーム(DataOutputStream/DataInputStream)
文字列やプリミティブ型を直接扱うことができ、開発の効率性が向上します。
// データの書き出し
DataOutputStream dataOut = new DataOutputStream(communicationSocket.getOutputStream());
dataOut.writeUTF("高レベルストリームを使用したメッセージ送信");
// データの読み取り
DataInputStream dataIn = new DataInputStream(clientConnection.getInputStream());
String receivedText = dataIn.readUTF();
System.out.println("受信テキスト: " + receivedText);
UDPプロトコルによる非接続型通信
UDP(User Datagram Protocol)は、相手との接続を確認せずにパケット(データ報)を送信します。オーバーヘッドが少ないため、リアルタイム性が求められる処理に適しています。
1. パケットの送信
送信側はDatagramSocketを使用し、宛先情報を含めたDatagramPacketを送信します。
DatagramSocket senderSocket = new DatagramSocket();
String content = "UDPによる通信テストデータ";
byte[] payload = content.getBytes();
// 宛先IPアドレスとポート番号を指定してパケットを作成
InetAddress targetAddress = InetAddress.getByName("localhost");
DatagramPacket packet = new DatagramPacket(payload, payload.length, targetAddress, 9500);
senderSocket.send(packet);
senderSocket.close();
2. パケットの受信
受信側は特定のポートに紐付けたDatagramSocketを用意し、空のバッファでパケットを待ち受けます。
// 指定したポートで待ち受け
DatagramSocket receiverSocket = new DatagramSocket(9500);
byte[] receiveBuffer = new byte[1024];
// 受信用のコンテナを作成
DatagramPacket incomingPacket = new DatagramPacket(receiveBuffer, receiveBuffer.length);
System.out.println("UDPパケットを待機中...");
receiverSocket.receive(incomingPacket); // パケットが到着するまで待機
// データの抽出
String result = new String(incomingPacket.getData(), 0, incomingPacket.getLength(), "UTF-8");
System.out.println("受信成功: " + result);
receiverSocket.close();