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() メソッドは、クライアントのソケットに接続されているサーバー上の新しいソケット参照を返します。


接続確立後は、I/Oストリームを使用して通信が行われます。各ソケットには出力ストリームと入力ストリームがあります。クライアントの出力ストリームはサーバーの入力ストリームに接続され、クライアントの入力ストリームはサーバーの出力ストリームに接続されます。


TCP は双方向通信プロトコルであるため、データは 2 つのデータ ストリームを通じて同時に送信できます。以下は、ソケットを実装するためにいくつかのクラスによって提供される便利なメソッドの完全なセットです。


ServerSocket クラスのメソッド

サーバー アプリケーションは、java.net.ServerSocket クラスを使用してポートを取得し、クライアントのリクエストをリッスンします。

ServerSocket クラスには 4 つの構築メソッドがあります:

シリアル番号メソッドの説明
1public ServerSocket(int port) が IOException をスローします
特定のポートにバインドされたサーバーソケットを作成します。
2public ServerSocket(int port, int backlog) が IOException をスローします
指定されたバックログを使用してサーバーソケットを作成し、それを指定されたローカルポート番号にバインドします。
3public ServerSocket(int port, int backlog, InetAddress address) が IOException をスローします
指定されたポート、リスニング バックログ、およびバインド先のローカル IP アドレスを使用してサーバーを作成します。
4public ServerSocket() が IOException をスローする
アンバインドされたサーバーソケットを作成します。

アンバインドサーバーソケットを作成します。 ServerSocket 構築メソッドが例外をスローしない場合は、アプリケーションが指定されたポートに正常にバインドされ、クライアント要求をリッスンしていることを意味します。

ServerSocket クラスの一般的なメソッドをいくつか示します:

シリアル番号メソッドの説明
1public int getLocalPort()
このソケットがリッスンしているポートを返します。
2public Socket accept() が IOException をスローする
このソケットへの接続をリッスンして受け入れます。
3public void setSoTimeout(int timeout)
タイムアウト値をミリ秒単位で指定して、SO_TIMEOUT を有効または無効にします。
4public void binding(SocketAddress host, int backlog)
ServerSocket を特定のアドレス (IP アドレスとポート番号) にバインドします。

Socket クラスのメソッド

java.net.Socket クラスは、クライアントとサーバーの両方が相互に通信するために使用するソケットを表します。クライアントはインスタンス化を通じて Socket オブジェクトを取得し、サーバーは accept() メソッドの戻り値を通じて Socket オブジェクトを取得します。

Socket クラスには 5 つの構築メソッドがあります。

シリアル番号メソッドの説明
1public Socket(String host, int port) が UnknownHostException、IOException をスローします。
ストリーム ソケットを作成し、指定されたホスト上の指定されたポート番号に接続します。
2public Socket(InetAddress host, int port) が IOException をスローします
ストリーム ソケットを作成し、指定された IP アドレスの指定されたポート番号に接続します。
3public Socket(String host, int port, InetAddress localAddress, int localPort) は IOException をスローします。
ソケットを作成し、指定されたリモート ホスト上の指定されたリモート ポートに接続します。
4public Socket(InetAddress host, int port, InetAddress localAddress, int localPort) が IOException をスローします。
ソケットを作成し、指定されたリモート アドレス上の指定されたリモート ポートに接続します。
5パブリックソケット()
システムのデフォルトタイプ SocketImpl を通じて未接続のソケットを作成します

Socket コンストラクターが返されると、単に Socket オブジェクトをインスタンス化するのではなく、実際に指定されたサーバーとポートへの接続を試みます。

いくつかの興味深いメソッドを以下にリストします。クライアントとサーバーの両方が Socket オブジェクトを持っているため、クライアントとサーバーの両方がこれらのメソッドを呼び出すことができることに注意してください。

シリアル番号方法の説明
1public void connect(SocketAddress host, int timeout) throws IOException
このソケットをサーバーに接続し、タイムアウト値を指定します。
2public InetAddress getInetAddress()
ソケット接続のアドレスを返します。
3public int getPort()
このソケットが接続されているリモート ポートを返します。
4public int getLocalPort()
このソケットがバインドされているローカル ポートを返します。
5パブリック SocketAddress getRemoteSocketAddress()
このソケットが接続されているエンドポイントのアドレスを返します。接続されていない場合は null を返します。
6public InputStream getInputStream() が IOException をスローする
このソケットの入力ストリームを返します。
7public OutputStream getOutputStream() が IOException をスローする
このソケットの出力ストリームを返します。
8public void close() が IOException をスローする
このソケットを閉じます。

InetAddress クラスのメソッド

このクラスは、インターネット プロトコル (IP) アドレスを表します。以下は、ソケット プログラミングでより便利なメソッドのリストです:

シリアル番号メソッドの説明
1static InetAddress getByAddress(byte[] addr)
元の IP アドレスを指定して InetAddress オブジェクトを返します。
2static InetAddress getByAddress(String host, byte[] addr)
指定されたホスト名と IP アドレスに基づいて InetAddress を作成します。
3static 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!