您的位置:首页 > 理论基础 > 计算机网络

java网络编程之Socket用法详解一

2017-09-05 21:11 555 查看
1.  构造Socket

(1).Socket()

(2).Socket(InetAddress address, int port)

(3).Socket(InetAddress address, int port, InetAddress localAdd, int localPort)

(4).Socket(String host, int port)

(5).Socket(String host, int port, InetAddress localAdd, int localPort)

除了第一个不带参数的构造方法外,其他构造方法都会试图连接服务器,如果连接成功,返回Socket对象,否则抛出IOException。

1.1 设定等待连接的超时时间

当客户端与服务器连接时,可能会等待一段时间。默认情况下,Socket的构造方法会一直等待下去,直到连接成功或者抛出异常。那该如何限定等待时间呢?此时就应该利用第一个无参的构造方法

Socket socket = new Socket();

SocketAddress address = new InetSocketAddress("localhost",1700);

socket.connect(address, 60000);  //单位是毫秒,等待时间为1min

Socket类的connect(SocketAddress endpoint, int timeout)负责连接服务器,参数endpoint指定服务器的地址,参数timeout指定超时的时间,以毫秒为单位,如果设为0,则永远不会超时。

1.2 设定服务器的地址

 InetAddress类表示服务器的IP地址,提供了一系列的静态工厂方法,用于构造自身的实例。

//返回本地主机的IP地址

InetAddress address1 = InetAddress.getLocalHost();

//返回代表222.34.5.7的IP地址

InetAddress address2 = InetAddress.getByName("222.34.5.7");

//返回域名为"www.javathinker.org"的IP地址

InetAddress address3 = InetAddress.getByName("www.javathinker.org");

1.3 设定客户端的地址

如果一个主机同时拥有两个以上的网络,那么就有可能拥有两个以上的IP地址,如一个主机在Internet网络中的IP地址是“222.67.1.34”,而在一个局域网中的IP地址是“112.5.4.3”.假定这个主机的客户程序希望和同一个局域网上的一个服务器程序(假设地址为112.5.4.45 : 1700)通信,可以按照如下方式构造Socket对象:

InetAddress remoteAddr = InetAddress.getByName("112.5.4.45");
InetAddress localAddr = InetAddress.getByName("112.5.4.3");
Socket socket = new Socket(remoteAddr, 1700, localAddr, 1234); //假设客户端使用的端口是1234

1.4 连接服务器时可能抛出的异常

当Socket的构造方法请求连接服务器时,可能抛出如下的异常:

(1)、UnknownHostException:如果无法识别主机的名字或IP地址,就会抛出此异常

(2)、ConnectException:如果服务器进程监听指定的端口,或者服务器进程拒绝连接,就会抛出此异常

(3)、SocketTimeoutException:如果等待连接超时,就会抛出此异常

(4)、BindException:如果无法把Socket对象与 指定的本地IP地址或端口绑定,就会抛出此异常

以下通过例子来演示:

public class ConnectTester {

public void connect(String host,int port){
SocketAddress address = new InetSocketAddress(host, port);
Socket socket = null;
String result = null;

try{
long beginTime = System.currentTimeMillis();  //开始时间
socket = new Socket();
socket.connect(address, 1000); //超时1秒
long endTime = System.currentTimeMillis();  //结束时间
result = (endTime-beginTime) + "毫秒";
}catch(BindException b){
result = "socket无法与指定的本地IP地址或端口绑定";
}catch(UnknownHostException u){
result = "无法识别主机的名字或IP地址";
}catch(ConnectException c){
result = "服务器拒绝连接";
}catch(SocketTimeoutException s){
result = "连接超时";
}catch(IOException e){
result = "不知原因";
}
if(socket!=null)
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(result);
}

public static void main(String[] args){
String host;
int port;
Scanner in = new Scanner(System.in);
host = in.nextLine();
port = in.nextInt();

ConnectTester t = new ConnectTester();
t.connect(host, port);
}

}

运行程序然后输入:

www.javathinker.org

80

a. 抛出UnknownHostException的情况:

    在控制台输入

    somehost

    80

    如果不存在名为"somehost"的主机,Socket的构造方法就会抛出UnknownHostException。

b.  抛出ConnectException的情况

    分两种情况

(1)、没有服务器进程指定的端口。

    在控制台输入

    localhost

    1700

    如果本地主机的1700端口没有被任何服务器进程监听,Socket构造方法就会抛出ConnectException

(2)、服务器进程拒绝连接

    ServerSocket(int port, int backlog)构造方法的第二个参数backlog,设定服务器请求连接的队列长度,如果请求连接已满,服务器就会拒绝其余的连接请求

    服务器类:

    public class SimpleServer {

public static void main(String[] args) throws Exception{
// TODO Auto-generated method stub
//连接请求的队列长度为2
ServerSocket server = new ServerSocket(1700, 2);
Thread.sleep(6000); //睡眠1分钟


}

    客户端类

    public class SimpleClient {

public static void main(String[] args) throws Exception{
// TODO Auto-generated method stub

for(int i=1;i<5;i++){
Socket socket = new Socket("localhost", 1700);
System.out.println("第"+i+"次连接成功");
}
}

}

先运行服务器类,再启动客户端类,可以在控制台看到



由于1700端口在之前可能已经打开过,这里再启动服务器的话有可能出错,所以没有得到上述结果的小伙伴请自行换个端口尝试,例如1701

其他异常情形可自己尝试更改数据进行测试。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息