netty入门——客户端与服务端通信(netty.io)-j9九游会登录

大家好!今天让小编来大家介绍下关于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

网站地图