netty--helloword程序
1、使用netty需要使用到下面的java包
netty-all-5.0.0.Alpha2.jar
我们来看下面具体的代码
1. 创建一个ServerBootstrap实例
2. 创建一个EventLoopGroup来处理各种事件,如处理链接请求,发送接收数据等。
3. 定义本地InetSocketAddress( port)好让Server绑定
4. 创建childHandler来处理每一个链接请求
5. 所有准备好之后调用ServerBootstrap.bind()方法绑定Server
package bhz.netty.test; 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; public class Server { public static void main(String[] args) throws Exception {
//1 第一个线程组 是用于接收Client端连接的 ,第一个线程也叫boss线程组
EventLoopGroup bossGroup = new NioEventLoopGroup();
//2 第二个线程组 是用于实际的业务处理操作的,第二个线程组也叫worker
EventLoopGroup workerGroup = new NioEventLoopGroup(); //3 创建一个辅助类Bootstrap,就是对我们的Server进行一系列的配置
ServerBootstrap b = new ServerBootstrap();
//把俩个工作线程组加入到Bootstrap中进来
b.group(bossGroup, workerGroup)
//我要指定使用NioServerSocketChannel这种类型的通道,不同的协议这里通道配置不一样
.channel(NioServerSocketChannel.class)
//一定要使用 childHandler 去绑定具体的 事件处理器
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel sc) throws Exception {
//通过channel的方法,把ServerHandler添加进去
sc.pipeline().addLast(new ServerHandler());
}
});
//还可以配置channel的缓冲区大小等 //绑定指定的端口 进行监听,这里必须调用sync()是异步操作
ChannelFuture f = b.bind(8765).sync(); //Thread.sleep(1000000);
//为了让服务器端程序一直运行,不会停止,等价于/Thread.sleep(1000000);
f.channel().closeFuture().sync(); bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully(); } }
package bhz.netty.test; /*
*注意所以的包都必须是netty的
*/
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.ReferenceCountUtil; public class ServerHandler extends ChannelHandlerAdapter { @Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception { //do something msg
ByteBuf buf = (ByteBuf)msg;
byte[] data = new byte[buf.readableBytes()];
buf.readBytes(data);
String request = new String(data, "utf-8");
System.out.println("Server: " + request);
//写给客户端
String response = "我是反馈的信息";
ctx.writeAndFlush(Unpooled.copiedBuffer("888".getBytes())).;
//.addListener(ChannelFutureListener.CLOSE); } @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
} }
客户端对应的代码:
package bhz.netty.test; import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.Unpooled;
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.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel; public class Client { public static void main(String[] args) throws Exception {
//客户端不需要boss线程组,只需要worker线程组就可以
EventLoopGroup workgroup = new NioEventLoopGroup();
//服务器端对应的ServerBootstrap
Bootstrap b = new Bootstrap();
b.group(workgroup)
//服务器端对应的是NioServerSocketChannel
.channel(NioSocketChannel.class)
//服务器端对应的是childhandle
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel sc) throws Exception {
sc.pipeline().addLast(new ClientHandler());
}
}); //ChannelFuture异步非阻塞的通道
ChannelFuture cf1 = b.connect("127.0.0.1", 8765).sync(); //buf
cf1.channel().writeAndFlush(Unpooled.copiedBuffer("777".getBytes())); cf1.channel().closeFuture().sync();
workgroup.shutdownGracefully(); }
}
package bhz.netty.test; import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.util.ReferenceCountUtil; public class ClientHandler extends ChannelHandlerAdapter { @Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
try {
//do something msg
ByteBuf buf = (ByteBuf)msg;
byte[] data = new byte[buf.readableBytes()];
buf.readBytes(data);
String request = new String(data, "utf-8");
System.out.println("Client: " + request); } finally {
ReferenceCountUtil.release(msg);
}
} @Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
第二个需要注意的地方
客户端多次调用write函数发送数据,但是最后才调用flush,server端收到的数据如下,server端只会收到一次数据,数据如下
所以在编写程序代码的时候,最好使用writeAndFlush()
第三个需要注意的地方
服务端收到客户端发送的数据,需要把数据回复给客户端,这里可以添加一个监听,监听客户端是否收到了服务器发送的数据,监听到客户端收到数据之后,服务端会主动关闭客户端和服务器端建立的连接,客户端的连接就没有了,但是服务器一直还运行
上述代码还有一个更简单的书写形式
在服务端的ServerHandle代码中添加
注意上面的操作是放在服务端中,如果放在客户端中,客户端把数据发送给服务器之后,如果客户端就调用上面的函数,当监听到服务器收到了客户端的数据之后,客户端就主动把连接关闭掉了,就会导致服务器端回复给客户端的数据客户端无法获取到。
netty--helloword程序的更多相关文章
- Netty 应用程序的一个一般准则:尽可能的重用 EventLoop,以减少线程创建所带来的开销。
Netty 系列一(核心组件和实例). - JMCui - 博客园 https://www.cnblogs.com/jmcui/p/9154842.html 阅读目录 一.概念 二.核心组件 三.实例 ...
- Netty入门二:开发第一个Netty应用程序
Netty入门二:开发第一个Netty应用程序 时间 2014-05-07 18:25:43 CSDN博客 原文 http://blog.csdn.net/suifeng3051/article/ ...
- Vivado的helloword程序:软件工程部分
建立工程 Export结束后,会自动启动SDK.界面如下.可以看到工程浏览器Project Explorer中已经有一个硬件平台hw_platform_0,里面有一系列配置和初始化文件.不要修改这些文 ...
- Vivado的helloword程序:硬件工程部分
硬件平台:ZedBoard软件平台:vivado2013.3 本示例通过综合.实现,生成比特流,发送到SDK实现.启动vivado并且创建一个项目根据提示操作一步步创建新项目的时候记得选择RTL Pr ...
- Netty4具体解释二:开发第一个Netty应用程序
既然是入门,那我们就在这里写一个简单的Demo,client发送一个字符串到server端,server端接收字符串后再发送回client. 2.1.配置开发环境 1.安装JDK 2.去官网下 ...
- Netty(一)——Netty入门程序
转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/7447618.html 有兴趣的可先了解下:4种I/O的对比与选型 主要内容包括: Netty开发环境的搭建 ...
- Netty实战二之自己的Netty应用程序
接下来我们将展示如何构建一个基于Netty的客户端和服务器,程序很简单:客户端将消息发送给服务器,而服务器再将消息回送给客户端,这将是一个对你而言很重要的第一个netty的实践经验. 1.设置开发环境 ...
- Netty权威指南之Netty入门程序
package com.hjp.netty.netty; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.Chan ...
- Netty入门程序(四)
maven创建project,引入依赖: <dependency> <groupId>io.netty</groupId> <artifactId>ne ...
- Flask初识之安装及HelloWord程序
Python 现阶段三大主流Web框架 Django Tornado Flask 对比 1.Django 主要特点是大而全,集成了很多组件,例如: Models Admin Form 等等, 不管你用 ...
随机推荐
- 获取Class实例的方式与类加载器
1. java.lang.Class: 是反射的源头 2.如何获取Class的实例(3种) 3.关于类的加载器 TestReflection2 package com.aff.reflection ...
- 【题解】P6218 [USACO06NOV] Round Numbers S
题目传送门 这是一道数位DP. 令 \(dp_{i,j,k}\) 为满足由 \(i\) 位组成,且其中有 \(j\) 个1,第 i 位(从右往左数)为 \(k\) 的二进制数的数量. 可以得出状态转移 ...
- node_modules内容太大导致webstrom非常卡
选中一个文件夹,例如node_modules,点击右键->mark directory as ->excluded,这样就可以把这个文件标记并排除出来,使webstorm不会扫描这个文件下 ...
- 解决pip._vendor.urllib3.exceptions.ReadTimeoutError: HTTPSConnectionPool(host='files.pythonhosted.org', port=443): Read timed out.问题
国内的其他镜像源清华大学 https://pypi.tuna.tsinghua.edu.cn/simple/阿里云 http://mirrors.aliyun.com/pypi/simple/中国科技 ...
- LayUI laydate日期选择器自定义 快捷选中今天、昨天 、本周、本月等等
1. 引入laydata插件 下载 https://blog-static.cnblogs.com/files/zhangning187/laydate.js laydate.js 替换laydate ...
- Rocket - diplomacy - TransferSizes
https://mp.weixin.qq.com/s/Sf0owQxWzxacVvykJZ5oTQ 介绍TransferSizes的实现. 1. 基本定义 从min到max的闭合 ...
- WebAPI之FormData
MDNformdata参考--https://developer.mozilla.org/zh-CN/docs/Web/API/FormData MDNformdata参考--https://deve ...
- js基本语法和数据类型
三种引入方式: 使用JavaScript:前缀构建执行JavaScript代码 使用<script></script>标签来包含JavaScript代码 <body> ...
- ASP.NET给图片自动添加水印
先建一个类,感觉注释已经很详细了,有不懂的欢迎评论 using System; using System.Collections.Generic; using System.Drawing; usin ...
- Java实现 LeetCode 134 加油站
134. 加油站 在一条环路上有 N 个加油站,其中第 i 个加油站有汽油 gas[i] 升. 你有一辆油箱容量无限的的汽车,从第 i 个加油站开往第 i+1 个加油站需要消耗汽油 cost[i] 升 ...