Java-ネットワーキング
ネットワーク プログラミングという用語 ネットワークを使用してすべてのデバイスが相互に接続されている複数のデバイス (コンピューター) で実行されるプログラムを作成することを指します。
J2SE API の java.net パッケージには、低レベルの通信の詳細を提供するクラスとインターフェースのコレクションが含まれており、目前の問題を解決することに重点を置いたプログラムを作成できます。
java.net パッケージは、2 つの一般的なネットワーク プロトコルのサポートを提供します −
- <リ>
TCP − TCP は Transmission Control Protocol の略で、2 つのアプリケーション間の信頼できる通信を可能にします。 TCP は通常、TCP/IP と呼ばれるインターネット プロトコル上で使用されます。
<リ>UDP − UDP は User Datagram Protocol の略で、アプリケーション間でデータのパケットを送信できるコネクションレス プロトコルです。
この章では、次の 2 つの主題についてよく理解できます −
- <リ>
ソケットプログラミング − これはネットワーキングで最も広く使用されている概念であり、非常に詳細に説明されています。
<リ>URL 処理 − これは別途カバーされます。 Java 言語での URL 処理について学ぶには、ここをクリックしてください。
ソケット プログラミング
ソケットは、TCP を使用して 2 台のコンピューター間の通信メカニズムを提供します。クライアント プログラムは、通信の最後にソケットを作成し、そのソケットをサーバーに接続しようとします。
接続が確立されると、サーバーは通信の最後にソケット オブジェクトを作成します。クライアントとサーバーは、ソケットへの書き込みとソケットからの読み取りによって通信できるようになりました。
java.net.Socket クラスはソケットを表し、java.net.ServerSocket クラスは、サーバー プログラムがクライアントをリッスンしてクライアントとの接続を確立するメカニズムを提供します。
次の手順は、ソケットを使用して 2 台のコンピューター間で TCP 接続を確立するときに発生します −
- <リ>
サーバーは ServerSocket オブジェクトをインスタンス化し、通信が行われるポート番号を示します。
<リ>サーバーは ServerSocket クラスの accept() メソッドを呼び出します。このメソッドは、クライアントが指定されたポートでサーバーに接続するまで待機します。
<リ>サーバーが待機した後、クライアントは接続先のサーバー名とポート番号を指定して Socket オブジェクトをインスタンス化します。
<リ>Socket クラスのコンストラクターは、指定されたサーバーとポート番号にクライアントを接続しようとします。通信が確立されると、クライアントはサーバーと通信できる Socket オブジェクトを持ちます。
<リ>サーバー側では、accept() メソッドは、クライアントのソケットに接続されているサーバー上の新しいソケットへの参照を返します。
接続が確立されると、I/O ストリームを使用して通信を行うことができます。各ソケットには、OutputStream と InputStream の両方があります。クライアントの OutputStream はサーバーの InputStream に接続され、クライアントの InputStream はサーバーの OutputStream に接続されます。
TCP は双方向通信プロトコルであるため、両方のストリームで同時にデータを送信できます。以下は、ソケットを実装するメソッドの完全なセットを提供する便利なクラスです。
ServerSocket クラス メソッド
java.net.ServerSocket クラスは、サーバー アプリケーションがポートを取得し、クライアント リクエストをリッスンするために使用されます。
ServerSocket クラスには 4 つのコンストラクターがあります −
| Sr.No. | 方法と説明 |
|---|---|
| 1 | public ServerSocket(int ポート) が IOException をスローする 指定されたポートにバインドされたサーバー ソケットの作成を試みます。ポートが別のアプリケーションによって既にバインドされている場合は、例外が発生します。 |
| 2 | public ServerSocket(int port, int backlog) が IOException をスローする 前のコンストラクターと同様に、backlog パラメーターは、待機キューに格納する受信クライアントの数を指定します。 |
| 3 | public ServerSocket(int ポート、int バックログ、InetAddress アドレス) が IOException をスローする 前のコンストラクターと同様に、InetAddress パラメーターはバインド先のローカル IP アドレスを指定します。 InetAddress は、複数の IP アドレスを持つ可能性のあるサーバーに使用され、サーバーがクライアント要求を受け入れる IP アドレスを指定できるようにします。 |
| 4 | public ServerSocket() が IOException をスローする バインドされていないサーバー ソケットを作成します。このコンストラクターを使用する場合は、サーバー ソケットをバインドする準備ができたら bind() メソッドを使用してください。 |
ServerSocket コンストラクターが例外をスローしない場合は、アプリケーションが指定されたポートに正常にバインドされ、クライアント要求の準備ができていることを意味します。
以下は、ServerSocket クラスの一般的なメソッドの一部です −
| Sr.No. | 方法と説明 |
|---|---|
| 1 | public int getLocalPort() サーバーソケットがリッスンしているポートを返します。このメソッドは、コンストラクターでポート番号として 0 を渡し、サーバーにポートを見つけさせる場合に便利です。 |
| 2 | public Socket accept() が IOException をスローする クライアントの着信を待ちます。このメソッドは、タイムアウト値が setSoTimeout() メソッドを使用して設定されていると仮定して、指定されたポートでクライアントがサーバーに接続するか、ソケットがタイムアウトするまでブロックします。それ以外の場合、このメソッドは無期限にブロックされます。 |
| 3 | public void setSoTimeout(int タイムアウト) accept() 中にサーバー ソケットがクライアントを待機する時間のタイムアウト値を設定します。 |
| 4 | public void bind(SocketAddress host, int backlog) SocketAddress オブジェクトで指定されたサーバーとポートにソケットをバインドします。引数なしのコンストラクターを使用して ServerSocket をインスタンス化した場合は、このメソッドを使用してください。 |
ServerSocket が accept() を呼び出すと、クライアントが接続するまでメソッドは戻りません。クライアントが接続した後、ServerSocket は未指定のポートに新しい Socket を作成し、この新しい Socket への参照を返します。クライアントとサーバーの間に TCP 接続が確立され、通信を開始できます。
ソケット クラス メソッド
java.net.Socket クラスは、クライアントとサーバーの両方が相互に通信するために使用するソケットを表します。クライアントは Socket オブジェクトをインスタンス化して取得しますが、サーバーは accept() メソッドの戻り値から Socket オブジェクトを取得します。
Socket クラスには、クライアントがサーバーに接続するために使用する 5 つのコンストラクターがあります −
| Sr.No. | 方法と説明 |
|---|---|
| 1 | public Socket(String host, int port) が UnknownHostException、IOException をスローします。 このメソッドは、指定されたポートで指定されたサーバーへの接続を試みます。このコンストラクターが例外をスローしない場合、接続は成功し、クライアントはサーバーに接続されます。 |
| 2 | パブリック ソケット (InetAddress ホスト、int ポート) が IOException をスローする このメソッドは、ホストが InetAddress オブジェクトによって示されることを除いて、前のコンストラクターと同じです。 |
| 3 | public Socket(String host, int port, InetAddress localAddress, int localPort) は IOException をスローします。 指定されたホストとポートに接続し、ローカル ホストの指定されたアドレスとポートにソケットを作成します。 |
| 4 | public Socket(InetAddress host, int port, InetAddress localAddress, int localPort) は IOException をスローします。 このメソッドは、ホストが String ではなく InetAddress オブジェクトによって示されることを除いて、前のコンストラクターと同じです。 |
| 5 | 公開ソケット() 未接続のソケットを作成します。 connect() メソッドを使用して、このソケットをサーバーに接続します。 |
Socket コンストラクターが戻ると、単に Socket オブジェクトをインスタンス化するのではなく、指定されたサーバーとポートに実際に接続しようとします。
ここでは、Socket クラスの重要なメソッドをいくつか示します。クライアントとサーバーの両方に Socket オブジェクトがあることに注意してください。したがって、これらのメソッドはクライアントとサーバーの両方から呼び出すことができます。
| Sr.No. | 方法と説明 |
|---|---|
| 1 | public void connect(SocketAddress host, int timeout) が IOException をスローする このメソッドは、ソケットを指定されたホストに接続します。このメソッドは、引数なしのコンストラクターを使用して Socket をインスタンス化する場合にのみ必要です。 |
| 2 | public InetAddress getInetAddress() このメソッドは、このソケットが接続されている他のコンピューターのアドレスを返します。 |
| 3 | public int getPort() リモート マシンでソケットがバインドされているポートを返します。 |
| 4 | public int getLocalPort() ローカル マシンでソケットがバインドされているポートを返します。 |
| 5 | public SocketAddress getRemoteSocketAddress() リモート ソケットのアドレスを返します。 |
| 6 | public InputStream getInputStream() が IOException をスローする ソケットの入力ストリームを返します。入力ストリームは、リモート ソケットの出力ストリームに接続されます。 |
| 7 | public OutputStream getOutputStream() が IOException をスローする ソケットの出力ストリームを返します。出力ストリームは、リモート ソケットの入力ストリームに接続されます。 |
| 8 | public void close() が IOException をスローする ソケットを閉じます。これにより、この Socket オブジェクトはサーバーに再度接続できなくなります。 |
InetAddress クラス メソッド
このクラスは、インターネット プロトコル (IP) アドレスを表します。以下は、ソケットプログラミングを行う際に必要となる便利なメソッドです -
| Sr.No. | 方法と説明 |
|---|---|
| 1 | static InetAddress getByAddress(byte[] addr) 生の IP アドレスを指定して InetAddress オブジェクトを返します。 |
| 2 | static InetAddress getByAddress(String host, byte[] addr) 指定されたホスト名と IP アドレスに基づいて InetAddress を作成します。 |
| 3 | static InetAddress getByName(String host) ホストの名前を指定して、ホストの IP アドレスを決定します。 |
| 4 | 文字列 getHostAddress() テキスト表現で IP アドレス文字列を返します。 |
| 5 | 文字列 getHostName() この IP アドレスのホスト名を取得します。 |
| 6 | static InetAddress InetAddress getLocalHost() ローカル ホストを返します。 |
| 7 | 文字列 toString() この IP アドレスを文字列に変換します。 |
ソケット クライアントの例
次の GreetingClient は、ソケットを使用してサーバーに接続し、グリーティングを送信して応答を待機するクライアント プログラムです。
例
// File Name GreetingClient.java
import java.net.*;
import java.io.*;
public class GreetingClient {
public static void main(String [] args) {
String serverName = args[0];
int port = Integer.parseInt(args[1]);
try {
System.out.println("Connecting to " + serverName + " on port " + port);
Socket client = new Socket(serverName, port);
System.out.println("Just connected to " + client.getRemoteSocketAddress());
OutputStream outToServer = client.getOutputStream();
DataOutputStream out = new DataOutputStream(outToServer);
out.writeUTF("Hello from " + client.getLocalSocketAddress());
InputStream inFromServer = client.getInputStream();
DataInputStream in = new DataInputStream(inFromServer);
System.out.println("Server says " + in.readUTF());
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
ソケット サーバーの例
次の GreetingServer プログラムは、Socket クラスを使用して、コマンドライン引数で指定されたポート番号でクライアントをリッスンするサーバー アプリケーションの例です。
例
// File Name GreetingServer.java
import java.net.*;
import java.io.*;
public class GreetingServer extends Thread {
private ServerSocket serverSocket;
public GreetingServer(int port) throws IOException {
serverSocket = new ServerSocket(port);
serverSocket.setSoTimeout(10000);
}
public void run() {
while(true) {
try {
System.out.println("Waiting for client on port " +
serverSocket.getLocalPort() + "...");
Socket server = serverSocket.accept();
System.out.println("Just connected to " + server.getRemoteSocketAddress());
DataInputStream in = new DataInputStream(server.getInputStream());
System.out.println(in.readUTF());
DataOutputStream out = new DataOutputStream(server.getOutputStream());
out.writeUTF("Thank you for connecting to " + server.getLocalSocketAddress()
+ "\nGoodbye!");
server.close();
} catch (SocketTimeoutException s) {
System.out.println("Socket timed out!");
break;
} catch (IOException e) {
e.printStackTrace();
break;
}
}
}
public static void main(String [] args) {
int port = Integer.parseInt(args[0]);
try {
Thread t = new GreetingServer(port);
t.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
クライアントとサーバーをコンパイルし、次のようにサーバーを起動します −
$ java GreetingServer 6066 Waiting for client on port 6066...
次のようにクライアントプログラムを確認してください −
出力
$ java GreetingClient localhost 6066 Connecting to localhost on port 6066 Just connected to localhost/127.0.0.1:6066 Server says Thank you for connecting to /127.0.0.1:6066 Goodbye!
Java