- 2.1. ソケット
- 2.2. InetAddressクラス
- 2.3. SocketAddress/InetSocketAddressクラス
- 2.4. Socketクラス
- 2.5. TCPサーバプログラム
- 2.6. TCPクライアントプログラム
- 2.7. プログラムの実行
2.6. TCPクライアントプログラム
次にクライアントアプリケーションを示します。キーボードからの入力をサーバプログラムに送信し、送り返されてきた文字列をコンソールに出力するプログラムです。空行の入力があった時、接続を切断して終了するようにします。
リスト EchoClient.java
import java.net.Socket;
import java.net.ServerSocket;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.IOException;
public class EchoClient {
public static final int ECHO_PORT = 10007;
public static void main(String args[]) {
Socket socket = null;
try {
socket = new Socket(args[0], ECHO_PORT);
System.out.println("接続しました"
+ socket.getRemoteSocketAddress());
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader keyIn = new BufferedReader(new InputStreamReader(System.in));
String input;
while ( (input = keyIn.readLine()).length() > 0 ) {
out.println(input);
String line = in.readLine();
if (line != null) {
System.out.println(line);
} else {
break;
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (socket != null) {
socket.close();
}
} catch (IOException e) {}
System.out.println("切断されました "
+ socket.getRemoteSocketAddress());
}
}
}
15行目で新しいソケットを作成しています。ここではString型のホスト名を指定するコンストラクタを利用しています。接続先ホスト名はコマンドライン引数で指定したものとし、ポート番号は10007としています。
socket = new Socket(args[0], ECHO_PORT);
16〜17行目では、接続されたソケットの接続先情報を表示しています。getRemoteSocketAddressメソッドは接続先のSocketAddressを返すメソッドです。
System.out.println("接続しました"
+ socket.getRemoteSocketAddress());
18〜20行目では、ソケットに対して入出力を行うためのReader/Writerおよび、キーボードからの入力を受け取るためのReaderを作成しています。
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader keyIn = new BufferedReader(new InputStreamReader(System.in));
21〜30行目で、サーバーとの通信処理を行っています。キーボードから入力された文字列をサーバに対して送信し、送り返されてきた文字列を表示します。ループによって空行が入力されるまで処理を繰り返しています。
String input;
while ( (input = keyIn.readLine()).length() > 0 ) {
out.println(input);
String line = in.readLine();
if (line != null) {
System.out.println(line);
} else {
break;
}
}
サーバの終了によってソケットの接続が切れた場合など、readLineメソッドの戻り値がnullとなることがあるので、そのときもループから抜けるようにしています。ソケット切断時は例外が発生する場合もあるので、例外処理も正しく記述しなければいけません。(ソケット切断時の動作はOSによって異なります。プロセスを強制終了した時、SolarisやLinuxではTCPコネクションの終了処理を正しく行うのに対し、WindowsではTCPコネクションの終了処理を行わないためです。)
33〜41行目のfinally節では、確実にソケットを切断するための処理を記述しています。ソケットは明示的に閉じる習慣をつけておきましょう。
} finally {
try {
if (socket != null) {
socket.close();
}
} catch (IOException e) {}
System.out.println("切断されました "
+ socket.getRemoteSocketAddress());
}

