浅いものから深いものまでの Java ネットワーク プログラミング 2 サーバーに接続するソケットと関連する例外の構築の詳細な紹介

黄舟
リリース: 2017-03-04 10:07:33
オリジナル
1647 人が閲覧しました

ソケットの構築方法とソケットの設定と例外

この記事ではソケットの構築方法とソケット関連のプロパティの設定と例外処理について紹介します

  • ソケットの構築

  • 待機タイムアウト時間を設定する

  • サーバーアドレスを設定します

  • クライアントアドレスを設定します

  • クライアントがサーバーに接続するときに発生する可能性のある例外


ケット

Socket の構築メソッドは次のとおりです。 いくつかのオーバーロード メソッド:

Socket();Socket(InetAddress address, int port)Socket(InetAddress address, int port, 
InetAddress localAddr, int localPort)Socket(Proxy proxy)Socket(SocketImpl impl)Socket(String host, int port)
Socket(String host, int port, InetAddress localAddr, int localPort)
ログイン後にコピー

最初のコンストラクターを除き、他のコンストラクターはサーバーとの接続を確立しようとします。接続が成功した場合は、Socket オブジェクトが返されます。何らかの理由で、IOException がスローされます。
次のコードは、ホスト上のポート 1 ~ 1024 をスキャンして、これらのポートがサーバー プログラムによって監視されているかどうかを判断します。

public class PortScanner {    public static void main(String[] args) {
        String host = "localhost";        new PortScanner().scan(host);
    }    public void scan(String host){
        Socket socket = null;        for(int i=0;i<1024;i++){            try {
                socket = new Socket(host, i);
                System.out.println("There is a server on port "+i);
            }  catch (IOException e) {
                System.out.println("Can&#39;t connect to port "+i);
            }finally{                if(socket!=null){                    try {
                        socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}
ログイン後にコピー

接続の確立を待機するタイムアウトを設定します

パラメーターなしでコンストラクターを使用してソケット接続タイムアウトを設定します:

Socket socket = new Socket();
SocketAddress endPoint = new InetSocketAddress("localhost", 8000);socket.connect(endPoint, 60000);
ログイン後にコピー

上記のコードは、このマシンで監視されている 8000 ポートに接続するために使用されることを示しています。接続を待つ最長時間は 1 分です。 1 分以内に接続が成功した場合、connect() メソッドは正常に戻ります。1 分以内に例外が発生した場合は、接続も例外もスローされません。その場合、例外 SocketTimeoutException がスローされます。 socket.connect(SocketAddress endpoint, int timeout); はサーバーへの接続を担当し、パラメーター endpoint はサーバー アドレスを指定し、パラメーター timeout はミリ秒単位でタイムアウトを設定します。パラメータ timeout が 0 の場合、タイムアウトしないことを意味します。 SocketTimeoutExceptionsocket. connect(SocketAddress endpoint, int timeout);负责连接服务器,参数endpoint指定服务器地址,参数timeout设定超时时间,以毫秒为单位。如果参数timeout为0,表示永远不超时。

设置服务器地址

Socket的构造方法中,除了第一个不带参数的构造方法,其他构造方法都需要指定服务器地址,包括服务器的IP或主机名,以及端口:
Socket(InetAddress address, int port)
Socket(String host, int port)
InetAddress类表示服务器的IP地址,InetAddress提供了很多静态方法:

    // 返回本地主机的IP地址
    InetAddress.getLocalHost();    // 返回代表10.202.164.65的IP地址
    InetAddress.getByName("10.202.164.65");    // 返回域名为&#39;www.csdn.net&#39;的ip地址
    InetAddress.getByName("www.csdn.net");
ログイン後にコピー

设置客户端的地址:

默认情况下,客户端的IP地址来自于客户端程序所在的主机,客户端的端口则由操作系统随机分配。但是Socket类还是提供了构造方法允许显式地设置客户端的IP和端口:

//参数localAddr和localPort用来设置客户端的IP和端口。
Socket(InetAddress address, int port, InetAddress localAddr, int localPort)
Socket(String host, int port, InetAddress localAddr, int localPort)
ログイン後にコピー

客户端连接服务器可能抛出的异常

当Socket构造方法请求连接服务器时,可能会抛出下面的异常:
• UnknownHostException:如果无法识别主机的名字或IP地址,就会抛出这种异常

• ConnectException:如果没有服务器进程监听指定的端口,或者服务器拒绝连接,就会抛出这种异常。

• SocketTimeoutException:如果等待连接超时,就会抛出这种异常。

• BindException:如果无法把Socket对象与指定的本地IP地址或端口绑定,就会抛出这种异常。

通过下面测试类为例,演示抛出异常的原因。

public class ConnectTester {    public static void main(String[] args) {
        String host = "www.csdn.net";        
        int port = 12312;        
        new ConnectTester().connect(host, port);
    }    public void connect(String host,int port){
        SocketAddress remoteAddress = new InetSocketAddress(host, port);
        Socket socket = null;
        String result = null;        
        try{
            socket = new Socket();            
            long start = System.currentTimeMillis();
            socket.connect(remoteAddress,1000);            
            long end = System.currentTimeMillis();
            result = (end-start)+"ms";
        }catch(BindException bindException){
            result = "BindException,Socket对象与指定的本地IP地址或端口绑定,异常";
        }catch (UnknownHostException unknownHostException) {
            result = "UnknownHostException,无法识别的主机";
        }catch (ConnectException connectException) {
            result = "ConnectException,连接被拒绝";
        }catch (SocketTimeoutException socketTimeoutException) {
            result = "SocketTimeoutException,连接超时";
        }catch(IOException e){
            result = "IOException,连接失败";
        }finally{            if(socket!=null){                
        try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        System.out.println(remoteAddress+" : "+result);
    }
}
ログイン後にコピー

• 抛出UnknownHostException情况:
如果无法识别主机的名字或IP地址,就会抛出这种异常。例如:host为:’ somehost11’。Socket的connect方法就会抛出UnknownHostException异常。
• 抛出ConnectException的情况:
在以下两种情况会抛出ConnectException。
1) 没有服务器进程监听指定的端口。例如:host为 ‘localhost’ port为 12321 。如果本机的12321端口没有被任何进程监听,则Socket连接方法会抛出ConnectException。
2) 服务器进程拒绝连接。介绍服务器进程拒绝客户的连接请求的情形。如下示例代码,一个简单的服务程序ServerSocket构造方法中的第二个参数表示请求队列的长度。如果队列的请求已满,服务器就会拒绝其余的请求。抛出ConnectException

public class SimplServer {    public static void main(String[] args) throws Exception{
        ServerSocket serverSocket = new ServerSocket(8888, 2);
        Thread.sleep(3600000);
    }
}
ログイン後にコピー
public class SimpleClient {    
public static void main(String[] args) throws Exception{
        String host = "localhost";        int port = 8888;
        Socket s1 = new Socket(host, port);
        System.out.println("第一次连接成功");
        Socket s2 = new Socket(host, port);
        System.out.println("第二次连接成功");
        Socket s3 = new Socket(host, port);
        System.out.println("第三次连接成功");
    }
}
ログイン後にコピー

• 抛出SocketTimeoutException的情形
如果客户端连接超时,就会抛出这种异常。修改 socket.connect(remoteAddress, 1);

サーバーアドレスを設定します

Socket 構築メソッドでは、パラメータのない最初の構築メソッドを除き、他の構築メソッドでは、サーバーの IP またはホスト名とポートを含むサーバー アドレスを指定する必要があります:

Socket(InetAddress address, int port)

Socket(String host, int port)

InetAddress クラスは、サーバーの IP アドレスを表します:

socket = new Socket();socket.connect(remoteAddress, 1000);
ログイン後にコピー

クライアントのアドレスを設定します:


デフォルトでは、クライアントの IP です。アドレス これはクライアント プログラムが配置されているホストから取得され、クライアントのポートはオペレーティング システムによってランダムに割り当てられます。ただし、Socket クラスは、クライアントの IP とポートを明示的に設定できる構築メソッドを引き続き提供します: 🎜
socket = new Socket();
socket.bind(new InetSocketAddress(InetAddress.getByName("222.34.5.6"), 5678));
socket.connect(remoteAddress, 1000);
ログイン後にコピー
🎜🎜サーバーへの接続時にクライアントによってスローされる可能性のある例外🎜🎜🎜Socket 構築メソッドが接続を要求するときサーバーに対して、次の例外がスローされる場合があります。 🎜• UnknownHostException: ホストの名前または IP アドレスが認識できない場合、この例外がスローされます。 🎜🎜• ConnectException: 指定されたポートをリッスンするサーバー プロセスが存在しない場合。 、またはサーバーが接続を拒否した場合、この例外がスローされます。 🎜🎜• SocketTimeoutException: この例外は、接続の待機がタイムアウトした場合にスローされます。 🎜🎜• BindException: この例外は、Socket オブジェクトを指定されたローカル IP アドレスまたはポートにバインドできない場合にスローされます。 🎜🎜 例外をスローする理由を示すために、次のテスト クラスを例として取り上げます。 🎜rrreee🎜• UnknownHostException のスロー: 🎜ホストの名前または IP アドレスが認識できない場合、この例外がスローされます。例: ホストは「somehost11」です。ソケットの connect メソッドは UnknownHostException をスローします。 🎜• ConnectExceptionがスローされる状況: 🎜ConnectExceptionは以下の2つの状況でスローされます。 🎜1) 指定されたポートでリッスンしているサーバー プロセスがありません。例: ホストは「localhost」、ポートは 12321 です。ローカル ポート 12321 がどのプロセスによっても監視されていない場合、Socket 接続メソッドは ConnectException をスローします。 🎜2) サーバープロセスが接続を拒否しました。サーバー プロセスがクライアントの接続要求を拒否する状況を紹介します。次のサンプルコードに示すように、単純なサービス プログラム ServerSocket の構築メソッドの 2 番目のパラメーターはリクエスト キューの長さを表します。キューがリクエストでいっぱいの場合、サーバーは残りのリクエストを拒否します。 ConnectExceptionのスロー🎜rrreeerrreee🎜• SocketTimeoutExceptionがスローされる状況 🎜クライアント接続がタイムアウトした場合、この例外がスローされます。 socket.connect(remoteAddress, 1); を元の 1000 ミリ秒から 1 ミリ秒に変更すると、タイムアウトの可能性が高くなります。 🎜🎜• BindException がスローされる状況: 🎜コード 🎜rrreee🎜 を次のように変更します。 🎜rrreee🎜 変更されたコードは、Socket のローカル IP アドレスを 222.34.5.6 に、ローカル ポートを 5678 に設定しようとします。このマシンに IP が割り当てられていない場合、またはポートが占有されている場合は、BindException が発生します。 🎜🎜 上記は、浅いものから深いものまで、ソケットの構築とサーバーに接続する関連する例外に関する Java ネットワーク プログラミングの詳細な紹介です。さらに関連するコンテンツについては、PHP 中国語 Web サイト (www.php.cn) に注目してください。 🎜🎜🎜🎜🎜
関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート