この記事ではWIN10にインストールしたJava 10.0.1を使っています。
#はじめに
システム間の通信を行うには、TCPとUDPというOSIのレイヤ4(トランスポート)のプロトコルがよく使われます。
TCPとUDPのメリットは以下となります:
TCP
- 信頼性が高い
UDP - スピードが早い
また、TCPとUDPはシステム間の通信をできますが、それ以外、通信するデータに対して何かI/O処理を行わないといけませんので、I/O処理の方式も必要です。ここはブロッキングと(BIO)かノンブロッキング(NIO)がよく使われいます。
今回はTCP/IP+BIOでシステム間の通信を実装してみます。
#実装#
TCP通信を行うには、ソケットというライブラリを利用します。
Java言語からSocket、ServerSocketを提供していので、今回はこれらを使ってTCP/IP+BIOを実装してみます。
(公式APIはここ:Socket、ServerSocket)
サーバ側のファイル(実はローカル)
ソケットを生成し、クライアント側のアクセスを待ち受けます
TcpServerファイル内容:
import java.io.*;
import java.net.*;
public class TcpServer{
public static void main (String[] argv) throws Exception{
try (
// 8001ポート番号を作成する
ServerSocket server = new ServerSocket(8001);
FileOutputStream fos = new FileOutputStream("server_recv.txt");
FileInputStream fis = new FileInputStream("server_send.txt");
){
System.out.println("wait access...");
// クライアント側のアクセスを待つ
Socket socket = server.accept();
System.out.println("client access.");
int ch;
// クライアント側から渡されたストリームをserver_recv.txtに書く
InputStream input = socket.getInputStream();
while ((ch = input.read()) != 0) {
fos.write(ch);
}
// server_send.txtに書いた内容ストリームでをクライアント側に渡す
OutputStream output = socket.getOutputStream();
while ((ch = fis.read()) != -1) {
output.write(ch);
}
// アクセス終了
socket.close();
System.out.println("accsess closed.");
} catch (Exception e) {
e.printStackTrace();
}
}
}
server_send.txt ファイル内容:
server_send
server_recv.txtは空ファイル
クライアント側のファイル
ソケットを生成し、指定されたサーバとポートをアクセスします
TcpClientファイル内容:
import java.io.*;
import java.net.*;
public class TcpClient{
public static void main (String[] argv) throws Exception{
try (
// 8001ポート番号をアクセス
Socket socket = new Socket("localhost", 8001);
FileOutputStream fos = new FileOutputStream("client_recv.txt");
FileInputStream fis = new FileInputStream("client_send.txt");
){
int ch;
// client_send.txtに書いた内容ストリームでをサーバ側に渡す
OutputStream output = socket.getOutputStream();
while ((ch = fis.read()) != -1) {
output.write(ch);
}
// サーバ側に「転送終了!」旨を渡す
output.write(0);
// サーバ側から渡されたストリームをclient_recv.txtに書く
InputStream input = socket.getInputStream();
while ((ch = input.read()) != -1) {
fos.write(ch);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
client_send.txt ファイル内容:
client_send
client_recv.txtは空ファイル
#実行#
TcpClient.javaとTcpServer.javaをそれぞれをjavacでコンパイルし、javaで実行します
- TcpServer.classを実行します
サーバを起動し、クライアント側の接続を待ち受け中:
PS C:\Users\ma\Documents\work\javaweb\1> java TcpServer
wait access...
- TcpClient.classを実行します
クライアントを起動し、サーバ側へアクセスします:
PS C:\Users\ma\Documents\work\javaweb\1> java TcpClient
サーバはクライアント側からの接続を処理したら終了します:
PS C:\Users\ma\Documents\work\javaweb\1> java TcpServer
wait access...
client access.
accsess closed.
PS C:\Users\ma\Documents\work\javaweb\1>
#結果検証#
server_recv.txt ファイル内容:
client_send
クライアント側から渡された内容(client_send.txt)を上書きすることを検証できました
client_recv.txtも同じくサーバ側から渡された内容(server_send.txt)を上書きされました:
server_send
#まとめ#
今回はJavaのSocket、ServerSocketライブラリを使ってTCP/IP+BIOの転送路を作りました。
サーバとクライアントの間に、データを双方向に送れることも検証しました。
#参考#
1.前橋和弥.2016.基礎からのWebアプリケーション開発入門.技術評論社.