大家好!今天让小编来大家介绍下关于netty入门——客户端与通信的问题,以下是酷知号的小编对此问题的归纳整理,让我们一起来看看吧。
netty简介
netty是一个基于ja nio 类库的异步通信框架,它的架构特点是:异步非阻塞、基于事件驱动、高性能、高可靠性和高可定制性。换句话说,netty是一个nio框架,使用它可以简单快速地开发网络应用程序,比如客户端和服务端的协议。netty大大简化了网络程序的开发过程比如tcp和udp的 socket的开发。netty 已逐渐成为 ja nio 编程的首选框架。
什么是物联网?
nio通信框架
物联网主要运用到netty哪些特性
a、tcp长连接
b、能够和各种序列化框架完美整合
为什么要使用netty,相对于其他通信框架mina有哪些优点
a、api使用简单,开发门槛低
b、功能强大,预置了多种编解码功能,支持多种主流协议
c、社区活跃,版本更新快
d、技术稳定可靠,如:elasticsearch、spark、dubbo、motan等开源框架底层通信采用的是netty
1、netty服务端编写
首先,netty通过serverbootstrap启动服务端代码,需要四步:
第一步,定义两个线程组,用来处理客户端通道的accept和读写事件
第二步,绑定服务端通道nioserversocketchannel
第三步,给读写事件的线程通道绑定handle,处理具体的业务逻辑
第四步,绑定监听
1.1、nettyserver——netty服务端编写
import io.netty.bootstrap.serverbootstrap;
import io.netty.channel.channelfuture;
import io.netty.channel.channelinitializer;
import io.netty.channel.channeloption;
import io.netty.channel.eventloopgroup;
import io.netty.channel.nio.nioeventloopgroup;
import io.netty.channel.socket.socketchannel;
import io.netty.channel.socket.nio.nioserversocketchannel;
import io.netty.handler.codec.delimiterbasedframedecoder;
import io.netty.handler.codec.delimiters;
/**
* netty服务端编写
*
* @author administrator
*
*/
public class nettyserver {
public static void main(string[] args) throws interruptedexception {
// 首先,netty通过serverbootstrap启动服务端
serverbootstrap server = new serverbootstrap();
eventloopgroup parentgroup = new nioeventloopgroup();
eventloopgroup childgroup =new nioeventloopgroup();
//第1步定义两个线程组,用来处理客户端通道的accept和读写事件
//parentgroup用来处理accept事件,childgroup用来处理通道的读写事件
//parentgroup获取客户端连接,连接接收到之后再将连接转发给childgroup去处理
server.group(parentgroup, childgroup);
//用于构造服务端套接字serversocket对象,标识当服务器请求处理线程全满时,用于临时存放已完成三次握手的请求的队列的最大长度。
//用来初始化服务端可连接队列
//服务端处理客户端连接请求是按顺序处理的,所以同一时间只能处理一个客户端连接,多个客户端来的时候,服务端将不能处理的客户端连接请求放在队列中等待处理,backlog参数指定了队列的大小。
server.option(channeloption.so_backlog, 128);
//第2步绑定服务端通道
server.channel(nioserversocketchannel.class);
//第3步绑定handler,处理读写事件,channelinitializer是给通道初始化
server.childhandler(new channelinitializer() {
@override
protected void initchannel(socketchannel ch) throws exception {
//解码器,接收的数据进行解码,一定要加在simpleserverhandler 的上面
//maxframelength表示这一贞最大的大小
//delimiter表示分隔符,我们需要先将分割符写入到bytebuf中,然后当做参数传入;
//需要注意的是,netty并没有提供一个delimiterbasedframedecoder对应的编码器实现(笔者没有找到),因此在发送端需要自行编码添加分隔符,如
分隔符
ch.pipeline().addlast(new delimiterbasedframedecoder(integer.max_value, delimiters.linedelimiter()[0]));
//把传过来的数据 转换成bytebuf
ch.pipeline().addlast(new simpleserverhandler());
}
});
//第4步绑定8080端口
channelfuture future = server.bind(8080).sync();
//当通道关闭了,就继续往下走
future.channel().closefuture().sync();
}
}
1.2、simpleserverhandler——处理客户端返回的数据
import ja.nio.charset.charset;
import io.netty.buffer.bytebuf;
import io.netty.buffer.unpooled;
import io.netty.channel.channelhandlercontext;
import io.netty.channel.channelinboundhandleradapter;
/**
* 处理客户端返回的数据
*
* @author administrator
*
*/
public class simpleserverhandler extends channelinboundhandleradapter {
/**
* 读取客户端通道的数据
*/
@override
public void channelread(channelhandlercontext ctx, object msg) throws exception {
//可以在这里面写一套类似springmvc的框架
//让simpleserverhandler不跟任何业务有关,可以封装一套框架
if(msg instanceof bytebuf){
system.out.println(((bytebuf)msg).tostring(charset.defaultcharset()));
}
//业务逻辑代码处理框架。。。
//返回给客户端的数据,告诉我已经读到你的数据了
string result = "hello client ";
bytebuf buf = unpooled.buffer();
buf.writebytes(result.getbytes());
ctx.channel().writeandflush(buf);
bytebuf buf2 = unpooled.buffer();
buf2.writebytes("
".getbytes());
ctx.channel().writeandflush(buf2);
system.out.println("==========");
}
}
//使用下面命令测试上面代码。
1.开启上面main方法。
2.执行一下命令
c:>telnet localhost 8080
随便输入,会发现eclipse控制台会监听到输入的内容,有个问题接收时一个字一个字接受,可以让他一行一行接收
2、netty客户端编写
第一步,连接到服务端
第二步,向服务端发送数据
第三步,处理服务端返回的数据
第四步,关闭连接
2.1、nettyclient——netty客户端编写
import com.alibaba.fastjson.jsonobject;
import com.dxfx.user.model.user;
import io.netty.bootstrap.bootstrap;
import io.netty.channel.channelfuture;
import io.netty.channel.channelinitializer;
import io.netty.channel.eventloopgroup;
import io.netty.channel.nio.nioeventloopgroup;
import io.netty.channel.socket.nio.niosocketchannel;
import io.netty.handler.codec.delimiterbasedframedecoder;
import io.netty.handler.codec.delimiters;
import io.netty.handler.codec.string.stringencoder;
import io.netty.util.attributekey;
/**
* netty客户端编写
* @author administrator
*
*/
public class nettyclient {
public static void main(string[] args) throws interruptedexception {
// 首先,netty通过serverbootstrap启动服务端
bootstrap client = new bootstrap();
//第1步 定义线程组,处理读写和链接事件,没有了accept事件
eventloopgroup group = new nioeventloopgroup();
client.group(group );
//第2步 绑定客户端通道
client.channel(niosocketchannel.class);
//第3步 给niosocketchannel初始化handler, 处理读写事件
client.handler(new channelinitializer() { //通道是niosocketchannel
@override
protected void initchannel(niosocketchannel ch) throws exception {
//字符串编码器,一定要加在simpleclienthandler 的上面
ch.pipeline().addlast(new stringencoder());
ch.pipeline().addlast(new delimiterbasedframedecoder(
integer.max_value, delimiters.linedelimiter()[0]));
//找到他的管道 增加他的handler
ch.pipeline().addlast(new simpleclienthandler());
}
});
//连接服务器
channelfuture future = client.connect("localhost", 8080).sync();
//发送数据给服务器
user user = new user();
user.setage(12);
user.setid(1);
user.setname("sssss");
future.channel().writeandflush(jsonobject.tojsonstring(user) "
");
for(int i=0;i<5;i ){
string msg = "ssss" i "
";
future.channel().writeandflush(msg);
}
//当通道关闭了,就继续往下走
future.channel().closefuture().sync();
//接收服务端返回的数据
attributekey key = attributekey.valueof("serverdata");
object result = future.channel().attr(key).get();
system.out.println(result.tostring());
}
}
2.2、simpleclienthandler——处理服务端返回的数据
import ja.nio.charset.charset;
import io.netty.buffer.bytebuf;
import io.netty.channel.channelhandlercontext;
import io.netty.channel.channelinboundhandleradapter;
import io.netty.util.attributekey;
/**
* 处理服务端返回的数据
*
* @author administrator
*
*/
public class simpleclienthandler extends channelinboundhandleradapter {
@override
public void channelread(channelhandlercontext ctx, object msg) throws exception {
if (msg instanceof bytebuf) {
string value = ((bytebuf) msg).tostring(charset.defaultcharset());
system.out.println("服务器端返回的数据:" value);
}
attributekey key = attributekey.valueof("serverdata");
ctx.channel().attr(key).set("客户端处理完毕");
//把客户端的通道关闭
ctx.channel().close();
}
}
3、netty服务端输出的信息
{"age":12,"id":1,"name":"sssss"}
==========
ssss0
==========
ssss1
==========
ssss2
==========
ssss3
==========
ssss4
==========
4、netty客户端输出的信息
服务器端返回的数据:hello client
客户端处理完毕
服务器端返回的数据:hello client
服务器端返回的数据:hello client
服务器端返回的数据:hello client
服务器端返回的数据:hello client
服务器端返回的数据:hello client
以上就是小编对于netty入门——客户端与服务端通信问题和相关问题的解答了,netty入门——客户端与服务端通信的问题希望对你有用!
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文链接:https://www.andon8.com/430200.html