ServerSocket和ServerSocketChannel实例
来源:互联网 发布:淘宝类目在哪里修改 编辑:程序博客网 时间:2024/06/01 18:12
1.传统Socket
传统Socket单线程只能处理一个连接,要处理多个连接需要借助线程或者线程池,但是这样比较消耗资源。
public class ServerSocketDemo { public static void main(String[] args) throws IOException { new ServerSocketDemo().start(8080); } private void start(int port) throws IOException { ServerSocket serverSocket = new ServerSocket(port,2000); System.out.println("server is start!"); //线程池可以处理多个连接比较消耗性能 ExecutorService executorService= Executors.newCachedThreadPool(); try { while (true) { //accept 会阻塞 Socket socket = serverSocket.accept(); System.out.println("有客户端连接来了"+socket.toString()); executorService.execute(new SocketHandler(socket)); } } catch (Exception ex) { System.out.println(ex.getMessage()); } finally { serverSocket.close(); } }}
public class SocketHandler implements Runnable { private Socket socket; public SocketHandler(Socket socket) { this.socket = socket; } public void run() { InputStream in = null; OutputStream out = null; try { in = socket.getInputStream(); out = socket.getOutputStream(); byte[] bytes = new byte[1024]; while (true) { //会阻塞 int n = in.read(bytes); if (n == -1) { break; } System.out.println(new String(bytes, 0, n)); out.write(bytes,0,n); } } catch (Exception ex) { System.out.println(ex.getMessage()); } finally { try { System.out.print("关闭 socket"); socket.close(); } catch (Exception ex) { System.out.println(ex.getMessage()); } try { if(in!=null) { in.close(); } } catch (Exception ex) { System.out.println(ex.getMessage()); } try { if(out!=null) { out.close(); } } catch (Exception ex) { System.out.println(ex.getMessage()); } } }}
2.NIO
java nio 借鉴了Linux下select、poll、epoll模型;其性能有很大的提高。
public class ServerSocketChannelDemo { private Selector selector; public void initServer(int port) throws IOException { //创建ServerSocketChannel ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); serverSocketChannel.configureBlocking(false); serverSocketChannel.socket().bind(new InetSocketAddress(port)); this.selector = Selector.open(); serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); } public void listen() throws IOException { System.out.println("server is start!"); while (true) { //这条语句会阻塞 selector.select(); Iterator<SelectionKey> iterator = this.selector.selectedKeys().iterator(); while (iterator.hasNext()) { SelectionKey key = iterator.next(); iterator.remove(); handler(key); } } } public void handler(SelectionKey key) throws IOException { if (key.isAcceptable()) { handlerAccept(key); } else if (key.isReadable()) { handlerReader(key); } } public void handlerAccept(SelectionKey key) throws IOException { ServerSocketChannel sever = (ServerSocketChannel) key.channel(); SocketChannel channel = sever.accept(); channel.configureBlocking(false); System.out.println("有客服端连接来了" + channel.toString()); channel.register(this.selector, SelectionKey.OP_READ); } public void handlerReader(SelectionKey key) throws IOException { SocketChannel socketChannel = (SocketChannel) key.channel(); ByteBuffer buffer = ByteBuffer.allocate(1024); //不会阻塞 int n = socketChannel.read(buffer); System.out.println(n); if (n > 0) { byte[] data = buffer.array(); System.out.println("服务端收到信息:" + new String(data, 0, n)); buffer.flip(); socketChannel.write(buffer); } else { System.out.println("clinet is close"); key.cancel(); } } public static void main(String[] args) throws IOException { ServerSocketChannelDemo sever = new ServerSocketChannelDemo(); sever.initServer(8081); sever.listen(); }}
NIO 的基本知识可以参考:
IO 模型
缓冲区
通道
值得说明是:
selector.select()是阻塞的,selector.select(1000)是非阻塞的(1000 表示等待时间)、selector.selectNow()也是非阻塞的、selector.wakeup()可以唤醒selector。
SelectionKey.OP_WRITE一般很少使用OP_WRITE表示底层缓冲区是否有空间,是则响应返还true。
0 0
- ServerSocket和ServerSocketChannel实例
- ServerSocketChannel 和SocketChannel代替ServerSocket和Socket
- 使用非阻塞ServerSocketChannel、SocketChannel代替ServerSocket和Socket
- 使用非阻塞ServerSocketChannel、SocketChannel代替ServerSocket和Socket
- 使用非阻塞ServerSocketChannel、SocketChannel代替ServerSocket和Socket
- 使用非阻塞ServerSocketChannel、SocketChannel代替ServerSocket和Socket
- 使用非阻塞ServerSocketChannel、SocketChannel代替ServerSocket和Socket
- 使用非阻塞ServerSocketChannel、SocketChannel代替ServerSocket和Socket
- Socket和ServerSocket实例
- ServerSocket和Socket通讯实例
- ServerSocket和ClientSocket控件通讯的实例
- NIO之ServerSocketChannel应用实例
- ServerSocketChannel
- ServerSocketChannel
- ServerSocketChannel
- Java NIO实例-ServerSocketChannel实现Socket传输
- socket和serversocket
- BCB ServerSocket和ClientSocket
- Android Intent 意图
- 华为OJ:数字颠倒
- 最优化算法
- 算法:反向输出字符串
- CSDN-Markdown用法简述
- ServerSocket和ServerSocketChannel实例
- 二分匹配,匈牙利算法
- sublime默认运行python3
- 建立mysql主从模式集群,实现mysql的读写分离方法
- 1012. 数字分类 (20)
- Spring装配-Java配置
- this、super、final关键字(以及final修饰基本数据类型和引用类型的区别)
- Java基础知识点
- Oracle_PL/SQl_基本语法