客户端
java.net.Socket
作用:用于建立连接和网络IO的操作。
构造:
主要方法:
//创建一个流套接字并将其连接到指定主机上的指定端口号 --发送连接请求?
//问题1:如果想设置与服务器建立连接有超时,how to do?
Socket socket = Socket(目标IP或域名, 目标端口);
//设置等待响应的超时时间
socket.setSoTimeout(int timeout);
//读取服务器端返回的流
BufferedReader in = new BufferedReader(
new InputStreamReader(Socket.getInputStream));
in.readLine();
//创建向服务器写入流
PrintWriter out = new PrintWriter(socket.getOutputStream(),true);
out.println("hello");
服务器
java.net.ServerSocket
构造方法:在指定端口创建服务器套接字,用于监听客户端的连接请求。如果该端口已绑定有server,则抛IOException(确切是BindException)。
java.net.Socket
作用:网络IO操作。
//创建绑定到特定端口的服务器套接字
//对本地指定端口监听客户端是否有建立连接的请求
ServerSocket ss = new ServerSocket(监听端口);
//ServerSocket 调用 accept() 将只阻塞此时间长度timeout
//即 最多会等待timeout时间阻塞来等待客户端建立连接的请求
ss.setSoTimeout(int timeout);
//接受客户端建立连接的请求,返回的Socket用于与client交互
Socket socket = ss.accept();
客户端,通常将读取来自服务器端的消息另起线程处理;
服务器端,主线程中serverSocket不断监听端口,看是否有客户端的连接请求,如果有则响应请求并建立连接创建Socket实例,通常为每个socket实例创建一个线程,在该线程中与客户端进行通信。
深入
通过Socket、ServerSocket可以实现比较简单的client/server通信。
为了更符合实际情况
变化1: 多个客户端,1个服务器端,多个客户端可同时发请求给服务器端,服务器端同时接受这些请求。
实现方式1:server为每个请求建一个socket。
产生的问题 :如果client数目很多,会导致产生很多socket实例,不仅消耗了服务器很多资源还会导致服务器必须能够支撑非常高的连接数 ;其次,生成socket(建立连接)是比较耗时的,频繁的创建会导致性能不足。
改进方式:由一个连接池 来维护socket,这样不仅能限制socket的数目,还避免了socket的重复创建带来的开销。
产生的问题 :连接池中socket数目有限,如果同时要用socket的请求很多,这样会造成激烈的竞争和等待。还有一个需要考虑是关于设置客户端超时 的问题 ,如果服务器负载比较大,处理请求变慢,会导致客户端无限等待响应,设置客户端超时是有必要的。
选择的处理方式:一连接一线程。ServerSocket通过accept获取socket后,将此socket放入一个线程中处理。通过限制创建的线程的数量 可以避免创建过多的线程。
##可参考学习下《java并发编程实践》ch6.1