Javaネットワークプログラミング
ネットワーク プログラミングとは、ネットワークを介して接続された複数のデバイス (コンピューター) 上で実行されるプログラムを作成することを指します。
java.net パッケージの J2SE API には、低レベルの通信の詳細を提供するクラスとインターフェイスが含まれています。これらのクラスとインターフェイスを直接使用して、通信の詳細ではなく問題の解決に集中できます。
java.net パッケージは、2 つの一般的なネットワーク プロトコルのサポートを提供します:
TCP: TCP は、Transmission Control Protocol の略語で、2 つのアプリケーション間の信頼性の高い通信を保証します。 TCP/IP として知られるインターネット プロトコルに一般的に使用されます。
UDP: UDP は User Datagram Protocol の略で、コネクションレス型プロトコルです。アプリケーション間で送信されるデータのパケットを提供します。
このチュートリアルでは主に次の 2 つのトピックについて説明します。
ソケットプログラミング: これは最も広く使用されているネットワーク概念であり、詳細に説明されています
URL 処理: この部分は別のスペースで説明されます。ここをクリックしてください。 Java 言語での URL 処理の詳細。
ソケット プログラミング
ソケットは、TCP を使用した 2 台のコンピューター間の通信メカニズムを提供します。 クライアント プログラムはソケットを作成し、サーバーのソケットへの接続を試みます。
接続が確立されると、サーバーは Socket オブジェクトを作成します。これで、クライアントとサーバーは、Socket オブジェクトへの書き込みと読み取りによって通信できるようになります。
java.net.Socket クラスはソケットを表し、java.net.ServerSocket クラスはサーバー プログラムがクライアントをリッスンしてクライアントとの接続を確立するためのメカニズムを提供します。
2 台のコンピューター間でソケットを使用して TCP 接続を確立する場合、次の手順が実行されます:
サーバーは、サーバー上のポートを介した通信を表す ServerSocket オブジェクトをインスタンス化します。
サーバーは ServerSocket クラスの accept() メソッドを呼び出し、クライアントがサーバー上の指定されたポートに接続するまで待機します。
サーバーが待機している間、クライアントはサーバー名とポート番号を指定して Socket オブジェクトをインスタンス化し、接続を要求します。
Socket クラスのコンストラクターは、クライアントを指定されたサーバーおよびポート番号に接続しようとします。通信が確立されると、サーバーと通信するための Socket オブジェクトがクライアント上に作成されます。
サーバー側では、accept() メソッドは、クライアントのソケットに接続されているサーバー上の新しいソケット参照を返します。
TCP は双方向通信プロトコルであるため、データは 2 つのデータ ストリームを通じて同時に送信できます。以下は、ソケットを実装するためにいくつかのクラスによって提供される便利なメソッドの完全なセットです。
ServerSocket クラスのメソッド
サーバー アプリケーションは、java.net.ServerSocket クラスを使用してポートを取得し、クライアントのリクエストをリッスンします。
ServerSocket クラスには 4 つの構築メソッドがあります:
シリアル番号 | メソッドの説明 |
1 | public ServerSocket(int port) が IOException をスローします 特定のポートにバインドされたサーバーソケットを作成します。 |
2 | public ServerSocket(int port, int backlog) が IOException をスローします 指定されたバックログを使用してサーバーソケットを作成し、それを指定されたローカルポート番号にバインドします。 |
3 | public ServerSocket(int port, int backlog, InetAddress address) が IOException をスローします 指定されたポート、リスニング バックログ、およびバインド先のローカル IP アドレスを使用してサーバーを作成します。 |
4 | public ServerSocket() が IOException をスローする アンバインドされたサーバーソケットを作成します。 |
アンバインドサーバーソケットを作成します。 ServerSocket 構築メソッドが例外をスローしない場合は、アプリケーションが指定されたポートに正常にバインドされ、クライアント要求をリッスンしていることを意味します。
ServerSocket クラスの一般的なメソッドをいくつか示します:
シリアル番号 | メソッドの説明 |
1 | public int getLocalPort() このソケットがリッスンしているポートを返します。 |
2 | public Socket accept() が IOException をスローする このソケットへの接続をリッスンして受け入れます。 |
3 | public void setSoTimeout(int timeout) タイムアウト値をミリ秒単位で指定して、SO_TIMEOUT を有効または無効にします。 |
4 | public void binding(SocketAddress host, int backlog) ServerSocket を特定のアドレス (IP アドレスとポート番号) にバインドします。 |
Socket クラスのメソッド
java.net.Socket クラスは、クライアントとサーバーの両方が相互に通信するために使用するソケットを表します。クライアントはインスタンス化を通じて Socket オブジェクトを取得し、サーバーは accept() メソッドの戻り値を通じて Socket オブジェクトを取得します。
Socket クラスには 5 つの構築メソッドがあります。
シリアル番号 | メソッドの説明 |
1 | public Socket(String host, int port) が UnknownHostException、IOException をスローします。 ストリーム ソケットを作成し、指定されたホスト上の指定されたポート番号に接続します。 |
2 | public Socket(InetAddress host, int port) が IOException をスローします ストリーム ソケットを作成し、指定された IP アドレスの指定されたポート番号に接続します。 |
3 | public Socket(String host, int port, InetAddress localAddress, int localPort) は IOException をスローします。 ソケットを作成し、指定されたリモート ホスト上の指定されたリモート ポートに接続します。 |
4 | public Socket(InetAddress host, int port, InetAddress localAddress, int localPort) が IOException をスローします。 ソケットを作成し、指定されたリモート アドレス上の指定されたリモート ポートに接続します。 |
5 | パブリックソケット() システムのデフォルトタイプ SocketImpl を通じて未接続のソケットを作成します |
Socket コンストラクターが返されると、単に Socket オブジェクトをインスタンス化するのではなく、実際に指定されたサーバーとポートへの接続を試みます。
いくつかの興味深いメソッドを以下にリストします。クライアントとサーバーの両方が Socket オブジェクトを持っているため、クライアントとサーバーの両方がこれらのメソッドを呼び出すことができることに注意してください。
シリアル番号 | 方法の説明 |
1 | public void connect(SocketAddress host, int timeout) throws IOException このソケットをサーバーに接続し、タイムアウト値を指定します。 |
2 | public InetAddress getInetAddress() ソケット接続のアドレスを返します。 |
3 | public int getPort() このソケットが接続されているリモート ポートを返します。 |
4 | public int getLocalPort() このソケットがバインドされているローカル ポートを返します。 |
5 | パブリック SocketAddress getRemoteSocketAddress() このソケットが接続されているエンドポイントのアドレスを返します。接続されていない場合は null を返します。 |
6 | public InputStream getInputStream() が IOException をスローする このソケットの入力ストリームを返します。 |
7 | public OutputStream getOutputStream() が IOException をスローする このソケットの出力ストリームを返します。 |
8 | public void close() が IOException をスローする このソケットを閉じます。 |
InetAddress クラスのメソッド
このクラスは、インターネット プロトコル (IP) アドレスを表します。以下は、ソケット プログラミングでより便利なメソッドのリストです:
シリアル番号 | メソッドの説明 |
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 | 静的InetAddress getLocalHost() ローカルホストを返します。 |
7 | 文字列 toString() この IP アドレスを文字列に変換します。 |
ソケットクライアントインスタンス
以下のGreetingClientは、ソケット経由でサーバーに接続してリクエストを送信し、応答を待つクライアントプログラムです。
// 文件名 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 プログラムは、ソケットを使用して指定されたポートをリッスンするサーバー側アプリケーションです。
// 文件名 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 コードをコンパイルし、次のコマンドを実行して、ポート番号 6066 を使用してサービスを開始します:
$ 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!