传统的socket io中,若是须要同时接受多个链接的时候。必需要使用多线程,为每个链接建立一个线程。这样在链接数量比较大的状况,线程的数量也随之变大。虽然这样编程简单,可是缺点也十分的明显,就是大量的线程占用的大量的资源(内存和cpu的开销)。无论怎么样,咱们先编写一段程序,了解一下io编程的特色。(ps:程序不是很完善,请多担待)编程
单线程服务端程序:网络
public class SingleThreadSocketServer { public static void main(String[] args) { ServerSocket serverSocket = null; BufferedReader bufferedReader = null; Socket socket = null; try { serverSocket = new ServerSocket(9999); //建立一个端口是9999的socket服务 socket = serverSocket.accept(); //一直监听端口是否有链接进来,没有链接进来的时候,这个方法会一直阻塞在这里。 bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); String str; while((str = bufferedReader.readLine()) != null) { //若是客户端发送quit消息服务端断开链接 if("quit".equals(str)) { break; } System.out.println("收到客户端发来的消息:" + str); } } catch (IOException e) { e.printStackTrace(); }finally { try { System.out.println("关闭链接!"); bufferedReader.close(); socket.close(); serverSocket.close(); } catch (IOException e) { e.printStackTrace(); } } } }
注意:上面的单线程服务端有着很大的缺点,就是只能接受一次链接,接受完一次链接以后,通信完事以后就关闭了。这很明显不是很爽的一个体验,因此咱们要进行优化。多线程
多线程服务端程序:socket
线程类:优化
public class SocketThread implements Runnable { private int index; private Socket socket; public SocketThread(Socket socket, int index) { this.socket = socket; this.index = index; } public void run() { InputStream inputStream = null; InputStreamReader inputStreamReader = null; BufferedReader bufferedReader = null; try { inputStream = socket.getInputStream(); inputStreamReader = new InputStreamReader(inputStream); bufferedReader = new BufferedReader(inputStreamReader); String content; while ( (content =bufferedReader.readLine()) != null) { System.out.println("第" + index + "个链接发来消息:" + content); } } catch (IOException e) { e.printStackTrace(); }finally { try{ System.out.println("关闭" + index + "号链接!"); bufferedReader.close(); inputStreamReader.close(); inputStream.close(); }catch (IOException e) { } } } }
服务端:ui
public class MoreThreadSocketServer { public static void main(String[] args) { try { ServerSocket serverSocket = new ServerSocket(9999); //建立一个socket服务,而且绑定9999端口 int index = 0; while (true) { index ++; Socket socket = serverSocket.accept(); Thread thread = new Thread(new SocketThread(socket, index)); thread.start(); } } catch (IOException e) { e.printStackTrace(); } } }
总结:从两个程序的对比能够看出来,基于io的socket编程是阻塞的,并且不能同时保持多个链接。若是要实现这个功能,必需要使用多线程。每个链接都须要一个线程来保持。这两个缺点在基于nio网络编程中将解决这个问题。this