1. 序章

このクイックチュートリアルでは、サーバーに接続されているクライアントコンピューターのIPアドレスを見つける方法を学習します。

TCP/IP通信に使用できるjava.net APIを探索できるように、単純なクライアントサーバーシナリオを作成します。

2. バックグラウンド

Javaアプリケーションは、インターネットを介したデータの通信と送信にソケットを使用します。 Javaは、クライアントアプリケーション用にjava.net.Socketクラスを提供します。

java.net.ServerSocket クラスは、 TCP /IPベースのサーバー側ソケットの実装に使用されます。 ただし、TCP/IPアプリケーションのみに焦点を当てましょう。

3. サンプルの使用例-ケース

システムでアプリケーションサーバーが実行されていると仮定します。 このサーバーは、クライアントにグリーティングメッセージを送信します。 この場合、サーバーは通信にTCPソケットを使用します。

アプリケーションサーバーは特定のTCPポートにバインドされています。 そのソケットアドレスは、そのポートとローカルネットワークインターフェイスのIPアドレスの組み合わせです。 このため、クライアントはサーバーへの接続にこの特定のソケットアドレスを使用する必要があります。

4. サンプルアプリケーション

ユースケースを定義したので、サーバーの構築から始めましょう。

4.1. アプリケーションサーバー

まず、着信接続要求をリッスンするためにServerSocketをインスタンス化する必要があります。 ServerSocket クラスのコンストラクターには、引数としてポート番号が必要です。

public class ApplicationServer {

    private ServerSocket serverSocket;
    private Socket connectedSocket;
  
    public void startServer(int port) throws IOException {
        serverSocket = new ServerSocket(port);
        connectedSocket = serverSocket.accept();
        //...

4.2. クライアントIPアドレスの取得

着信クライアント用のSocketを確立したので、クライアントのIPアドレスを取得する方法を見てみましょう。 Socket インスタンスには、リモートクライアントのソケットアドレスが含まれています。 getRemoteSocketAddressメソッドを使用してこれを検査できます。

getRemoteSocketAddressメソッドは、SocketAddressタイプのオブジェクトを返します。 これは抽象Javaクラスです。 この例では、TCP / IP接続であることがわかっているため、InetSocketAddressにキャストできます。

InetSocketAddress socketAddress = (InetSocketAddress) connectedSocket.getRemoteSocketAddress();

すでに見てきたように、ソケットアドレスはIPアドレスとポート番号の組み合わせです。 getAddress を使用してIPアドレスを取得できます。これにより、InetAddressオブジェクトが返されます。 ただし、 getHostAddressを使用して、IPアドレスの文字列表現を取得することもできます

String clientIpAddress = socketAddress.getAddress()
    .getHostAddress();

4.3. クライアントへのグリーティングメッセージの送信

これで、サーバーとクライアントはグリーティングメッセージを交換できます。

String msg = in.readLine();
System.out.println("Message received from the client :: " + msg);
PrintWriter out = new PrintWriter(connectedSocket.getOutputStream(), true);
out.println("Hello Client !!");

5. アプリケーションをテストする

次に、コードをテストするためのクライアントアプリケーションを作成しましょう。 このクライアントは別のコンピューターで実行され、サーバーに接続します。

5.1. クライアントアプリケーションを構築する

まず、IPアドレスとポート番号を使用してサービスへのSocket接続を確立する必要があります。

public class ApplicationClient {
    public void connect(String ip, int port) throws IOException {
        clientSocket = new Socket(ip, port);
    }
}

サーバーアプリケーションと同様に、BufferedReaderPrintWriterを使用してソケットの読み取りと書き込みを行います。 サーバーにメッセージを送信するために、接続されたソケットに書き込むメソッドを作成しましょう。

public void sendGreetings(String msg) throws IOException {
    out.println(msg);
    String reply = in.readLine();
    System.out.println("Reply received from the server :: " + reply);
}

5.2. アプリケーションを実行する

次に、クライアントアプリケーションを実行して、空きポートを選択します。

その後、別のPCからクライアントアプリケーションを起動する必要があります。 この例では、サーバーマシンのIPアドレスが 192.168.0.100 であり、ポート5000が空いているとします。

java -cp com.baeldung.clientaddress.ApplicationClient 192.168.0.100 5000 Hello

ここでは、クライアントとサーバーが同じネットワーク上にあると想定しています。 クライアントがサーバーへの接続に成功すると、クライアントのIPアドレスがサーバーコンソールに出力されます。

たとえば、クライアントのIPアドレスが192.168.0.102の場合、コンソールに表示されるはずです。

IP address of the connected client :: 192.168.0.102

5.3. バックグラウンドで何が起こったのですか?

一般に、アプリケーションサーバーが起動すると、 ServerSocket は、指定されたポート番号とワイルドカードIPアドレスを使用してソケットオブジェクトをインスタンス化します。 その後、ステータスを着信接続要求の「リスニング」に変更します。 次に、クライアントが接続要求を送信すると、 ServerSocket は、acceptメソッドを呼び出して新しいソケットをインスタンス化します。

新しく作成されたソケットインスタンスには、サーバーとリモートクライアントのIPアドレスとポートが含まれています。 サーバーのIPアドレスの場合、 ServerSocket クラスは、着信要求を受信したローカルネットワークインターフェイスのIPアドレスを使用します。 次に、リモートクライアントのIPアドレスを取得するために、受信したTCPパケットのIPヘッダーをデコードし、送信元アドレスを使用します。

6. 結論

この記事では、サンプルのクライアントサーバーユースケースを定義し、 Javaソケットプログラミングを使用して、サーバーに接続されているクライアントのIPアドレスを見つけました。

いつものように、このアプリケーションのコードはGitHubから入手できます。