高性能网络通信框架Netty-Java NIO基础

三、使用 Java NIO 搭建简单的客户端与服务端实现网络通讯

本节我们使用JDK中原生 NIO API来创建一个简单的TCP客户端与服务器交互的网络程序。

3.1 客户端程序

这个客户端功能是当客户端连接到服务端后,给服务器发送一个Hello,然后从套接字里面读取服务器端返回的内容并打印,具体代码如下:

640?wx_fmt=png

640?wx_fmt=png

640?wx_fmt=png

  • 代码(1)分别创建了一个发送和接受buffer,用来发送数据时候byte化内容和接受数据。

  • 代码(2)获取一个客户端套接字通道。

  • 代码(3)设置socket通道为非阻塞模式,默认是阻塞模式。

  • 代码(4)(5)获取一个选择器,然后注册客户端套接字通道到该选择器,并且设置感兴趣的事情为0,就是不对任何事件感兴趣。

  • 代码(6)(7)调用套接字通道的connect方法,连接服务器(服务器套接字地址为127.0.0.1:7001),由于步骤(3)设置了为非阻塞,所以步骤(6)马上会返回。代码(7)判断连接是否已经完成,如果没有,则设置选择器去监听OP_CONNECT事件,也就是指明对该事件感兴趣。

  • 然后进入while循环进行事件处理,其中代码(8)选择已经就绪的网络IO事件,如果当前没有就绪的则阻塞当前线程。当有就绪事件后,会返回获取的事件个数,会执行代码(9)具体取出来具体事件列表。

  • 代码(10)循环处理所有就绪事件,代码(10.1)迭代出一个事件key,然后从集合中删除,代码(10.2)获取事件key感兴趣的标志,代码(10.3)则看兴趣集合里面是否有OP_CONNECT,如果有则说明有OP_CONNECT事件已经就绪了,那么执行步骤(10.3.1)等待客户端与服务端完成三次握手,然后步骤(10.3.2)(10.3.3)写入hello server,im a client到服务器端。然后代码(10.3.4)设置对OP_READ事件感兴趣。

  • 代码(10.4)则看如果当前事件key是OP_READ事件,说明服务器发来的数据已经在接受buffer就绪了,客户端可以去具体拿出来了,然后代码10.4.1从客户端套接字里面读取数据并打印。

注:设置套接字为非阻塞后,connect方法会马上返回的,所以需要根据结果判断是否为链接建立OK了,如果没有成功,则需要设置对该套接字的op_connect事件感兴趣,在这个事件到来的时候还需要调用finishConnect方法来具体完成与服务器的链接,在finishConnect返回true后说明链接已经建立完成了,则这时候可以使用套接字通道发送数据到服务器,并且设置堆该套接字的op_read事件感兴趣,从而可以监听到服务端发来的数据,并进行处理。

3.2 服务端程序

服务端程序代码如下:

640?wx_fmt=png

640?wx_fmt=png

640?wx_fmt=png

  • 代码(1)分别创建了一个发送和接受buffer,用来发送数据时候byte化内容,和接受数据。

  • 代码(2)获取一个服务端监听套接字通道。

  • 代码(3)设置socket通道为非阻塞模式,默认是阻塞模式。

  • 代码(4)获取与该通道关联的服务端套接字

  • 代码(5)绑定服务端套接字监听端口为7001

  • 代码(6)(7) 获取一个选择器,并注册通道到选择器,选择对OP_ACCEPT事件感兴趣,到这里服务端已经开始监听客户端链接了。

  • 代码(8) 具体处理事件,8.1选择当前就绪的事件,8.2遍历所有就绪事件,顺序调用processSelectedKey进行处理。

  • 代码(8.2.1) 当前事件key对应的OP_ACCEPT事件,则执行代码8.2.1.1获取已经完成三次握手的链接套接字,并通过代码8.2.1.2设置该链接套接字为非阻塞模式,通过代码8.2.1.3注册该链接套接字到选择器,并设置对对OP_READ事件感兴趣。

  • 代码(8.2.2) 判断如果当前事件key为OP_READ则通过代码8.2.2.1链接套接字里面获取客户端发来的数据,通过代码8.2.2.2发送数据到客户端。

注:在这个例子里面监听套接字serverSocket和serverSocket接受到的所有链接套接字都注册到了同一个选择器上,其中processSelectedKey里面8.2.1是用来处理serverSocket接受的新链接的,8.2.2是用来处理链接套接字的读写的。

到这里服务端和客户端就搭建好了,首先启动服务器,然后运行客户端,会输入如下:

640?wx_fmt=png

简单分析下结果:

  • 服务器端启动后,会先输出----Server Started----

  • 客户端启动后去链接服务器端,三次握手完毕后,服务器会获取op_accept事件,会通过accept获取链接套接字,所以输出了:

  • 然后客户端接受到三次握手信息后,获取到了op_connect事件,所以输出:

  • 服务端收到数据后,选择器会选择出op_read事件,读取客户端发来的内容,并发送回执到客户端:

  • 客户端收到服务器端回执后,选择器会选择出op_read事件,所以客户端会读取服务器端发来的内容,所以输出:

最后

想了解JDK NIO和更多Netty基础的可以 阅读原文

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值