Jadual Kandungan
Socket构造方法和Socket的设置与异常
构造Socket
设置等待建立连接的超时时间
设置服务器地址
设置客户端的地址:
客户端连接服务器可能抛出的异常
Rumah Java javaTutorial Java网络编程由浅入深二 Socket的构造和连接服务端的相关异常 的详细介绍

Java网络编程由浅入深二 Socket的构造和连接服务端的相关异常 的详细介绍

Mar 04, 2017 am 10:07 AM

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)
Salin selepas log masuk

除了第一个构造器外,其他构造器都会尝试与服务器建立连接,如果连接成功返回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't connect to port "+i);
            }finally{                if(socket!=null){                    try {
                        socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}
Salin selepas log masuk

设置等待建立连接的超时时间

使用不带参数的构造方法,设置socket连接超时时间:

Socket socket = new Socket();
SocketAddress endPoint = new InetSocketAddress("localhost", 8000);socket.connect(endPoint, 60000);
Salin selepas log masuk

以上代码表示用于连接本机上监听的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");    // 返回域名为'www.csdn.net'的ip地址
    InetAddress.getByName("www.csdn.net");
Salin selepas log masuk

设置客户端的地址:

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

//参数localAddr和localPort用来设置客户端的IP和端口。
Socket(InetAddress address, int port, InetAddress localAddr, int localPort)
Socket(String host, int port, InetAddress localAddr, int localPort)
Salin selepas log masuk

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

当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);
    }
}
Salin selepas log masuk

• 抛出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);
    }
}
Salin selepas log masuk
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("第三次连接成功");
    }
}
Salin selepas log masuk

• 抛出SocketTimeoutException的情形
如果客户端连接超时,就会抛出这种异常。修改 socket.connect(remoteAddress, 1);由原来的1000毫秒修改为1毫秒,这样增加了超时的可能性。

• 抛出BindException的情形:
将代码

socket = new Socket();socket.connect(remoteAddress, 1000);
Salin selepas log masuk

修改为:

socket = new Socket();
socket.bind(new InetSocketAddress(InetAddress.getByName("222.34.5.6"), 5678));
socket.connect(remoteAddress, 1000);
Salin selepas log masuk

修改后的代码试图把Socket的本地IP地址设为222.34.5.6,把本地端口设置为5678。如果本机不具有该IP,或者端口被占用,那么就会出现BindException。

 以上就是Java网络编程由浅入深二 Socket的构造和连接服务端的相关异常 的详细介绍的内容,更多相关内容请关注PHP中文网(www.php.cn)!


Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn

Tag artikel panas

Notepad++7.3.1

Notepad++7.3.1

Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1

Hantar Studio 13.0.1

Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6

Dreamweaver CS6

Alat pembangunan web visual

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Akar Kuasa Dua di Jawa Akar Kuasa Dua di Jawa Aug 30, 2024 pm 04:26 PM

Akar Kuasa Dua di Jawa

Nombor Sempurna di Jawa Nombor Sempurna di Jawa Aug 30, 2024 pm 04:28 PM

Nombor Sempurna di Jawa

Penjana Nombor Rawak di Jawa Penjana Nombor Rawak di Jawa Aug 30, 2024 pm 04:27 PM

Penjana Nombor Rawak di Jawa

Nombor Armstrong di Jawa Nombor Armstrong di Jawa Aug 30, 2024 pm 04:26 PM

Nombor Armstrong di Jawa

Weka di Jawa Weka di Jawa Aug 30, 2024 pm 04:28 PM

Weka di Jawa

Soalan Temuduga Java Spring Soalan Temuduga Java Spring Aug 30, 2024 pm 04:29 PM

Soalan Temuduga Java Spring

Nombor Smith di Jawa Nombor Smith di Jawa Aug 30, 2024 pm 04:28 PM

Nombor Smith di Jawa

Cuti atau kembali dari Java 8 Stream Foreach? Cuti atau kembali dari Java 8 Stream Foreach? Feb 07, 2025 pm 12:09 PM

Cuti atau kembali dari Java 8 Stream Foreach?

See all articles