(3)详解ServerSocket类

来源:互联网 发布:维纳滤波算法 编辑:程序博客网 时间:2024/05/29 12:41
ServerSocket类用来实现服务器套接字。服务器套接字等待请求通过网络传入。它基于该请求执行某些操作,然后可能向请求者返回结果。
一、构造方法 
ServerSocket有以下几中常用的构造方法:
(1) ServerSocket()
(2) ServerSocket(int port)
(3) ServerSocket(int port, int backlog)
(4) ServerSocket(int port, int backlog, InetAddress bindAddr)

其中,port为端口号,InteAddress为IP地址,backlog表示请求队列的长度,先说一说backlog的作用,当有一个Socket向服务器发出连接请求时,此连接请求进入请求队列,当请求队列满,而又有Socket对象发出连接请求时,此连接会被拒绝,客户端抛出ConnectException。

除了第一种不带参数的构造方法外,其他构造方法都使是服务器与特定端口绑定。如果无法绑定到对应端口,会抛出BindException,一般端口被占用,或者操作系统不允许普通用户绑定1~1023之间的端口,就会造成此异常。

如果把port设置为0,则端口由操作系统随机分配,这种端口称为匿名端口,通常不会使用匿名端口,因为客户端需要明确服务器的端口才可以向服务器发出连接请求。
和Socket类一样,对于有多个IP的主机,我们采用第(4)种构造方法来设置项用的IP;

而第(1)种构造方法存在的意义是,有的服务器选项需要在绑定端口之前设置,这个时候就需要先创建ServerSocket对象,再设置选项,最后再绑定端口,如以下例子:
ServerSocket serverSocket = new SernerSocket();serverSocket.serReuseAddress(true);   //设置ServerSocket选项serverSocket.bind(new InteSocketAddress(8000));   //绑定端口
如果把上面代码改成:
ServerSocket serverSocket = new SernerSocket(8000);serverSocket.serReuseAddress(true);
则这个选项设置无效
二、方法
ServerSocket中常用的方法相对于Socket少很多,下面说一下常用的一些方法:
1.从ServerSocket 中获取信息的方法:
getInetAddress();   // 返回此服务器套接字的本地地址。返回类型为SocketAddress
getLocalPort();   // 返回此套接字在其上侦听的端口。返回类型为int
getLocalSocketAddress();   //返回此套接字绑定的端点的地址,如果尚未绑定则返回 null。返回类型为SocketAddress

2.接收连接请求和关闭ServerSocket对象:
accept()方法:
该方法从连接请求队列中获取一个客户端请求,然后创建与客户端连接的Socket对象,并返回。如果队列中没有连接请求,此方法会一直等待下去,直到收到连接请求才返回,之后服务器从Socket对象中获取输入流和输出流和客户端交换数据,如果发送数据时客户端断开连接,服务器会抛出SocketException异常,通信完成后,应在finally块应关闭Socket对象,释放资源。

close()方法:
调用该方法使服务器释放端口,并断开所有与客户端之间的连接。当一个服务器运行结束时,即使没有执行该方法,也会释放端口,因此服务器并不一定要在结束之前执行close()方法。

ServerSocket提供了两种方法来判断服务器的关闭状态:
isBound();   //返回 ServerSocket 的绑定状态。
isClosed();   //返回 ServerSocket 的关闭状态。

3.设置Socket属性的相关方法:
ServerSocket方法有以下几种设置选项:
(1)SO_TIMEOUT
setSoTimeout(int timeout);   // 通过指定超时值启用/禁用 SO_TIMEOUT,以毫秒为单位。
该选项表示accept()方法等待客户端连接的时间,当accept()方法 在超时时间内没有获得连接,就会抛出SocketTImeoutException。

(2)SO_REUSEADDR
setReuseAddress(boolean on);   //启用/禁用 SO_REUSEADDR 套接字选项。
和Socket的setReuseAddress(boolean on)方法一样,当网络上仍然有旧数据向ServerSocket传输,是否允许新的ServerSocket绑定到与旧的ServerSocket 同样的端口上,在某些操作系统上允许重用端口,有些则不允许。很多服务器程序都是用固定的端口,当程序关闭后,端口可能还被占用一段时间,如果此时立刻重启服务器,服务器就会无法绑定端口,抛出BindException异常。为了确保不发生这种异常,就可以调用ServerSocket的setReuseAddress(boolean on)方法:
if(!serverSocket.getResuseAddress()) serverSocket.setReuseAddress(boolean on);
之前在上边提到了,该方法必须在绑定端口前设置。

(3)SO_RCVBUF
setReceiveBufferSize(int size);   //为从此 ServerSocket 接受的套接字的 SO_RCVBUF 选项设置默认建议值。
设置缓冲大小,和Socket的该选项一样,这里不重复叙述。

获取这些选项值的get方法在这里也省略。如果大家想了解更多关于Socket和ServerSocket,可以查看JDK文档。