文档章节

java nio--采用Selector实现Socket通信

HiAscend
 HiAscend
发布于 2017/07/05 20:39
字数 941
阅读 3
收藏 0
点赞 0
评论 0

server:

  1 /**
  2  * 选择器服务端
  3  * Created by ascend on 2017/6/9 9:30.
  4  */
  5 public class SelectorServer {
  6     //    public final static String REMOTE_IP = "192.168.0.44";
  7     public final static String REMOTE_IP = "127.0.0.1";
  8     public final static int PORT = 17531;
  9     private static ByteBuffer bb = ByteBuffer.allocate(1024);
 10     private static ServerSocketChannel ssc;
 11     private static boolean closed = false;
 12 
 13     public static void main(String[] args) throws IOException {
 14         //先确定端口号
 15         int port = PORT;
 16         if (args != null && args.length > 0) {
 17             port = Integer.parseInt(args[0]);
 18         }
 19         //打开一个ServerSocketChannel
 20         ssc = ServerSocketChannel.open();
 21         //获取ServerSocketChannel绑定的Socket
 22         ServerSocket ss = ssc.socket();
 23         //设置ServerSocket监听的端口
 24         ss.bind(new InetSocketAddress(port));
 25         //设置ServerSocketChannel为非阻塞模式
 26         ssc.configureBlocking(false);
 27         //打开一个选择器
 28         Selector selector = Selector.open();
 29         //将ServerSocketChannel注册到选择器上去并监听accept事件
 30         SelectionKey selectionKey = ssc.register(selector, SelectionKey.OP_ACCEPT);
 31 
 32 
 33         while (!closed) {
 34             //这里会发生阻塞,等待就绪的通道,但在每次select()方法调用之间,只有一个通道就绪了。
 35             int n = selector.select();
 36             //没有就绪的通道则什么也不做
 37             if (n == 0) {
 38                 continue;
 39             }
 40             //获取SelectionKeys上已经就绪的集合
 41             Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
 42 
 43             //遍历每一个Key
 44             while (iterator.hasNext()) {
 45                 SelectionKey sk = iterator.next();
 46                 //通道上是否有可接受的连接
 47                 if (sk.isAcceptable()) {
 48                     ServerSocketChannel sscTmp = (ServerSocketChannel) sk.channel();
 49                     SocketChannel sc = sscTmp.accept(); // accept()方法会一直阻塞到有新连接到达。
 50                     sc.configureBlocking(false);
 51                     sc.register(selector, SelectionKey.OP_READ | SelectionKey.OP_WRITE);
 52                 } else if (sk.isReadable()) {   //通道上是否有数据可读
 53                     try {
 54                         readDataFromSocket(sk);
 55                     } catch (IOException e) {
 56                         sk.cancel();
 57                         continue;
 58                     }
 59                 }
 60                 if (sk.isWritable()) {  //测试写入数据,若写入失败在会自动取消注册该键
 61                     try {
 62                         writeDataToSocket(sk);
 63                     } catch (IOException e) {
 64                         sk.cancel();
 65                         continue;
 66                     }
 67                 }
 68                 //必须在处理完通道时自己移除。下次该通道变成就绪时,Selector会再次将其放入已选择键集中。
 69                 iterator.remove();
 70             }//. end of while
 71 
 72         }
 73 
 74     }
 75 
 76 
 77 
 78     /**
 79      * 发送测试数据包,若失败则认为该socket失效
 80      *
 81      * @param sk SelectionKey
 82      * @throws IOException IOException
 83      */
 84     private static void writeDataToSocket(SelectionKey sk) throws IOException {
 85         SocketChannel sc = (SocketChannel) sk.channel();
 86         bb.clear();
 87         String str = "server data";
 88         bb.put(str.getBytes());
 89         while (bb.hasRemaining()) {
 90             sc.write(bb);
 91         }
 92     }
 93 
 94     /**
 95      * 从通道中读取数据
 96      *
 97      * @param sk SelectionKey
 98      * @throws IOException IOException
 99      */
100     private static void readDataFromSocket(SelectionKey sk) throws IOException {
101         SocketChannel sc = (SocketChannel) sk.channel();
102         bb.clear();
103         List<Byte> list = new ArrayList<>();
104         while (sc.read(bb) > 0) {
105             bb.flip();
106             while (bb.hasRemaining()) {
107                 list.add(bb.get());
108             }
109             bb.clear();
110         }
111         byte[] bytes = new byte[list.size()];
112         for (int i = 0; i < bytes.length; i++) {
113             bytes[i] = list.get(i);
114         }
115         String s = (new String(bytes)).trim();
116         if (!s.isEmpty()) {
117             if ("exit".equals(s)){
118                 ssc.close();
119                 closed = true;
120             }
121             System.out.println("服务器收到:" + s);
122         }
123     }
124 
125 }

client:

 1 /**
 2  *
 3  * Created by ascend on 2017/6/13 10:36.
 4  */
 5 public class Client {
 6 
 7     @org.junit.Test
 8     public void test(){
 9         Socket socket = new Socket();
10         try {
11             socket.connect(new InetSocketAddress(SelectorServer.REMOTE_IP,SelectorServer.PORT));
12             DataOutputStream out = new DataOutputStream(socket.getOutputStream());
13             out.write("exit".getBytes());
14             out.flush();
15             out.close();
16             socket.close();
17         } catch (IOException e) {
18             e.printStackTrace();
19         }
20     }
21 
22     public static void main(String[] args) {
23         new Thread(new ClientThread()).start();
24     }
25 
26     public void checkStatus(String input){
27         if ("exit".equals(input.trim())) {
28             System.out.println("系统即将退出,bye~~");
29             System.exit(0);
30         }
31     }
32 
33 
34 }
35 
36 class ClientThread implements Runnable {
37     private SocketChannel sc;
38     private boolean isConnected = false;
39     Client client = new Client();
40 
41     public ClientThread(){
42         try {
43             sc = SocketChannel.open();
44             sc.configureBlocking(false);
45             sc.connect(new InetSocketAddress(SelectorServer.REMOTE_IP,SelectorServer.PORT));
46             while (!sc.finishConnect()) {
47                 System.out.println("同" + SelectorServer.REMOTE_IP + "的连接正在建立,请稍等!");
48                 Thread.sleep(10);
49             }
50             System.out.println("连接已建立,待写入内容至指定ip+端口!时间为" + System.currentTimeMillis());
51         } catch (IOException | InterruptedException e) {
52             e.printStackTrace();
53         }
54     }
55 
56     @Override
57     public void run() {
58         try {
59             while (true){
60                 Scanner scanner = new Scanner(System.in);
61                 System.out.print("请输入要发送的内容:");
62                 String writeStr = scanner.nextLine();
63                 client.checkStatus(writeStr);
64                 ByteBuffer bb = ByteBuffer.allocate(writeStr.length());
65                 bb.put(writeStr.getBytes());
66                 bb.flip(); // 写缓冲区的数据之前一定要先反转(flip)
67                 while (bb.hasRemaining()){
68                     sc.write(bb);
69                 }
70                 bb.clear();
71             }
72         } catch (IOException e) {
73             e.printStackTrace();
74             if (Objects.nonNull(sc)) {
75                 try {
76                     sc.close();
77                 } catch (IOException e1) {
78                     e1.printStackTrace();
79                 }
80             }
81         }finally {
82             if (Objects.nonNull(sc)) {
83                 try {
84                     sc.close();
85                 } catch (IOException e1) {
86                     e1.printStackTrace();
87                 }
88             }
89         }
90     }
91 }

 

本文转载自:http://www.cnblogs.com/adeng/p/7049812.html

共有 人打赏支持
HiAscend
粉丝 0
博文 24
码字总数 923
作品 0
东城
程序员
Java NIO原理图文分析及代码实现

前言: 最近在分析hadoop的RPC(Remote Procedure Call Protocol ,远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。可以参考:http://baik...

phacks
2015/08/19
0
0
Java NIO原理图文分析及代码实现

Java IO 在Client/Server模型中,Server往往需要同时处理大量来自Client的访问请求,因此Server端需采用支持高并发访问的架构。一种简单而又直接的解决方案是“one-thread-per-connection”。...

只想一个人静一静
2014/02/22
0
1
Java NIO原理图文分析及代码实现

前言: 最近在分析hadoop的RPC(Remote Procedure Call Protocol ,远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。可以参考:http://baik...

SunnyWu
2014/11/05
0
1
Java NIO原理 图文分析及代码实现

Java NIO原理图文分析及代码实现 前言: 最近在分析hadoop的RPC(Remote Procedure Call Protocol ,远程过程调用协议,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术...

囚兔
2015/04/29
0
0
java NIO原理及通信模型

Java NIO是在jdk1.4开始使用的,它既可以说成“新IO”,也可以说成非阻塞式I/O。下面是java NIO的工作原理: 由一个专门的线程来处理所有的IO事件,并负责分发。 事件驱动机制:事件到的时候...

柳哥
2015/02/15
0
4
最近仔细研究了一下Java的NIO以及线程并发,搞清了点思路,特作笔记如下(NIO篇)

[转]http://www.cnblogs.com/feidao/archive/2005/07/15/193788.html 因为前段时间的项目需要写一些高性能服务器,结果写出来的结果是五花八门,我们要求使用NIO编写异步服务器,但是竟然有人...

风林火山
2010/12/26
0
1
Apache Mina 网络通信

Apache Mina Server 是一个网络通信应用框架,也就是说,它主要是对基于TCP/IP、UDP/IP协议栈的通信框架(当然,也可以提供JAVA 对象的序列化服务、虚拟机管道通信服务等),Mina 可以帮助我...

Mr&Cheng
2013/01/20
0
0
Java NIO 机制分析(一) Java IO的演进

一、引言 Java1.4之前的早期版本,Java对I/O的支持并不完善,开发人员再开发高性能I/O程序的时候,会面临一些巨大的挑战和困难,主要有以下一些问题: (1)没有数据缓冲区,I/O性能存在问题...

宸明
04/20
0
0
【远程调用框架】如何实现一个简单的RPC框架(四)优化二:改变底层通信框架

【如何实现一个简单的RPC框架】系列文章: 【远程调用框架】如何实现一个简单的RPC框架(一)想法与设计 【远程调用框架】如何实现一个简单的RPC框架(二)实现与使用 【远程调用框架】如何实...

wsl_Mr
2017/10/20
0
0
Kafka源码分析-序列3 -Producer -Java NIO(Reactor VS Peactor)

上一篇我们分析了Metadata的更新机制,其中涉及到一个问题,就是Sender如何跟服务器通信,也就是网络层。同很多Java项目一样,Kafka client的网络层也是用的Java NIO,然后在上面做了一层封装...

tantexian
2017/11/07
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

32.filter表案例 nat表应用 (iptables)

10.15 iptables filter表案例 10.16/10.17/10.18 iptables nat表应用 10.15 iptables filter表案例: ~1. 写一个具体的iptables小案例,需求是把80端口、22端口、21 端口放行。但是,22端口我...

王鑫linux
今天
0
0
shell中的函数&shell中的数组&告警系统需求分析

20.16/20.17 shell中的函数 20.18 shell中的数组 20.19 告警系统需求分析

影夜Linux
今天
0
0
Linux网络基础、Linux防火墙

Linux网络基础 ip addr 命令 :查看网口信息 ifconfig命令:查看网口信息,要比ip addr更明了一些 centos 7默认没安装ifconfig命令,可以使用yum install -y net-tools命令来安装。 ifconfig...

李超小牛子
今天
1
0
[机器学习]回归--Decision Tree Regression

CART决策树又称分类回归树,当数据集的因变量为连续性数值时,该树算法就是一个回归树,可以用叶节点观察的均值作为预测值;当数据集的因变量为离散型数值时,该树算法就是一个分类树,可以很...

wangxuwei
昨天
1
0
Redis做分布式无锁CAS的问题

因为Redis本身是单线程的,具备原子性,所以可以用来做分布式无锁的操作,但会有一点小问题。 public interface OrderService { public String getOrderNo();} public class OrderRe...

算法之名
昨天
9
0
143. Reorder List - LeetCode

Question 143. Reorder List Solution 题目大意:给一个链表,将这个列表分成前后两部分,后半部分反转,再将这两分链表的节点交替连接成一个新的链表 思路 :先将链表分成前后两部分,将后部...

yysue
昨天
1
0
数据结构与算法1

第一个代码,描述一个被称为BankAccount的类,该类模拟了银行中的账户操作。程序建立了一个开户金额,显示金额,存款,取款并显示余额。 主要的知识点联系为类的含义,构造函数,公有和私有。...

沉迷于编程的小菜菜
昨天
1
0
从为什么别的队伍总比你的快说起

在机场候检排队的时候,大多数情况下,别的队伍都要比自己所在的队伍快,并常常懊悔当初怎么没去那个队。 其实,最快的队伍只能有一个,而排队之前并不知道那个队快。所以,如果有六个队伍你...

我是菜鸟我骄傲
昨天
1
0
分布式事务常见的解决方案

随着互联网的发展,越来越多的多服务相互之间的调用,这时候就产生了一个问题,在单项目情况下很容易实现的事务控制(通过数据库的acid控制),变得不那么容易。 这时候就产生了多种方案: ...

小海bug
昨天
3
0
python从零学——scrapy初体验

python从零学——scrapy初体验 近日因为一些事情,需要从网上爬取一些东西,故而想通过使用爬虫来顺便学习下强大的python。现将一些学习中遇到的问题记录下来,以便日后查询 1. 开发环境的准...

咾咔叽
昨天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部