Java ServerSocket与Socket交互

ServerSocket与Socket的区别
ServerSocket
ServerSocket对象可以监听一个固定的端口,但不能主动发起连接。
- 创建ServerSocket通过构造函数,可以确定监听端口(port)**、客户端连接请求的队列长度(backlog)、服务端绑定IP(bindAddr)**。
1
2
3
4ServerSocket() throws IOException;
ServerSocket(int port) throws IOException;
ServerSocket(int port, int backlog) throws IOException;
ServerSocket(int port, int backlog, InetAddress bindAddr) throws IOException;
如果端口被占用或者没有权限使用某些端口会抛出BindException错误。譬如1~1023的端口需要管理员才拥有权限绑定。
如果设置端口为0,则系统会自动为其分配一个端口。
监听端口
1
Socket client = serverSocket.accept();
accept()函数可以使Server端的程序处于等待状态,程序将一直阻塞直到捕捉到一个来自Client端的请求,并返回一个用于与该Client通信的Socket对象。此后Server程序只要向这个Socket对象读写数据,就可以实现向远端的Client读写数据。结束监听时。关闭ServerSocket
1
serverSocket.close();
在关闭ServerSocket后,将释放其绑定的端口。
Socket
用于发起Socket连接,并且是通讯的数据通道。
创建Socket
1
2
3
4
5Socket();
Socket(InetAddress address, int port) throws UnknownHostException, IOException;
Socket(InetAddress address, int port, InetAddress localAddress, int localPort)throws IOException;
Socket(String host, int port)throws UnknownHostException, IOException;
Socket(String host, int port, InetAddress localAddress, int localPort)throws IOException;通过构造函数可以确定目的主机IP(host)**、目的主机端口(port)、本地IP(localAddress)、本地端口(localPort)**。
Socket常用方法
1
2
3
4
5
6getInetAddress(); //远程服务端的IP地址
getPort(); //远程服务端的端口
getLocalAddress(); //本地客户端的IP地址
getLocalPort(); //本地客户端的端口
getInputStream(); //获得输入流
getOutStream(); //获得输出流Socket状态
1
2
3isClosed(); //连接是否已关闭,若关闭,返回true;否则返回false
isConnect(); //如果曾经连接过,返回true;否则返回false
isBound(); //如果Socket已经与本地一个端口绑定,返回true;否则返回false
注意:在发送和接收数据后,需要调用分别调用shutdownOutput()和shutdownInput(),告诉对方输入输出已经结束。
服务端设计方法
服务器端设置通常有两种方式:单线程方式和多线程方式。在Web服务器中,多线程方式更常见。
多线程方式结构通常如下:
1 | public void service(){ |
在多线程的管理上,特别是实际生产环境中,通常使用线程池的方式来实现。