首頁 > Java > java教程 > 主體

Java網路程式設計由淺入深二 Socket的建構和連接服務端的相關異常 的詳細介紹

黄舟
發布: 2017-03-04 10:07:33
原創
1644 人瀏覽過

Socket建構方法與Socket的設定與例外

本文將介紹Socket的建構方法與Socket的相關屬性設定與例外處理

  • #建構Socket

  • #設定等待逾時時間

  • ##設定伺服器位址

  • 設定客戶端位址

  • 客戶端連線伺服器可能出現的例外


建構Socket

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 socket = new Socket();
SocketAddress endPoint = new InetSocketAddress("localhost", 8000);socket.connect(endPoint, 60000);
登入後複製

以上程式碼表示用於連接本機上監聽的8000端口,等待連接的最長時間為1分鐘。如果在1分鐘內連接成功,則connect()方法順利返回;如果在1分鐘之內出現異常,則拋出異常;如果超過1分鐘,既沒有連接成功,也沒有拋出異常,那麼會拋出

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);由原來的1000毫秒修改為1毫秒,這樣增加了超時的可能性。

•   拋出BindException的情形:

將程式碼

socket = new Socket();socket.connect(remoteAddress, 1000);
登入後複製

修改為:

socket = new Socket();
socket.bind(new InetSocketAddress(InetAddress.getByName("222.34.5.6"), 5678));
socket.connect(remoteAddress, 1000);
登入後複製

修改後的程式碼試圖把Socket的本機IP位址設為222.34. 5.6,把本地埠設定為5678。如果本機不具有該IP,或連接埠被佔用,那麼就會出現BindException。

 以上就是Java網路程式設計由淺入深二 Socket的建構與連接服務端的相關異常 的詳細介紹的內容,更多相關內容請關注PHP中文網(www.php.cn)!



#

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!