所用jar包

netty-all-4.1.30.Final.jar 密码:rzwe

NettyConfig.java,存放连接的客户端

 import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor; public class NettyConfig { /**
* 存储每一个客户端接入进来时的channel对象
*/
public static ChannelGroup group = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE); }

Server.java,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.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.ServerSocketChannel;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel; public class Server {
private int port;
private ServerSocketChannel serverSocketChannel; public Server(int port){
this.port = port;
bind();
} private void bind() {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
//服务端要建立两个group,一个负责接收客户端的连接,一个负责处理数据传输
//连接处理group
EventLoopGroup boss = new NioEventLoopGroup();
//事件处理group
EventLoopGroup worker = new NioEventLoopGroup();
ServerBootstrap bootstrap = new ServerBootstrap();
// 绑定处理group
bootstrap.group(boss, worker).channel(NioServerSocketChannel.class)
//保持连接数
.option(ChannelOption.SO_BACKLOG, 300)
//有数据立即发送
.option(ChannelOption.TCP_NODELAY, true)
//保持连接
.childOption(ChannelOption.SO_KEEPALIVE, true)
//处理新连接
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel sc) throws Exception {
// 增加任务处理
ChannelPipeline p = sc.pipeline();
p.addLast(
// //使用了netty自带的编码器和解码器
// new StringDecoder(),
// new StringEncoder(),
//心跳检测,读超时,写超时,读写超时
//new IdleStateHandler(5, 0, 0, TimeUnit.SECONDS),
//自定义的处理器
new ServerHandler());
}
}); //绑定端口,同步等待成功
ChannelFuture future;
try {
future = bootstrap.bind(port).sync();
if (future.isSuccess()) {
serverSocketChannel = (ServerSocketChannel) future.channel();
System.out.println("服务端启动成功,端口:"+port);
} else {
System.out.println("服务端启动失败!");
} //等待服务监听端口关闭,就是由于这里会将线程阻塞,导致无法发送信息,所以我这里开了线程
future.channel().closeFuture().sync();
} catch (Exception e) {
e.printStackTrace();
}
finally {
//优雅地退出,释放线程池资源
boss.shutdownGracefully();
worker.shutdownGracefully();
}
}
});
thread.start();
} public void sendMessage(Object msg){
if(serverSocketChannel != null){
serverSocketChannel.writeAndFlush(msg);
}
} public static void main(String[] args) {
Server server = new Server(8088);
}
}

ServerHandler.java,业务处理

 import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter; public class ServerHandler extends ChannelInboundHandlerAdapter { /**
* 客户端与服务端创建连接的时候调用
*/
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("客户端与服务端连接开始...");
NettyConfig.group.add(ctx.channel());
} /**
* 客户端与服务端断开连接时调用
*/
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
System.out.println("客户端与服务端连接关闭...");
NettyConfig.group.remove(ctx.channel());
} /**
* 服务端接收客户端发送过来的数据结束之后调用
*/
@Override
public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
ctx.flush();
System.out.println("信息接收完毕...");
} /**
* 工程出现异常的时候调用
*/
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
} /**
* 服务端处理客户端websocket请求的核心方法,这里接收了客户端发来的信息
*/
@Override
public void channelRead(ChannelHandlerContext channelHandlerContext, Object info) throws Exception {
System.out.println("接收到了:"+info);
ByteBuf buf = (ByteBuf) info;
byte[] req = new byte[buf.readableBytes()];
buf.readBytes(req);
String body = new String(req, "UTF-8");
System.out.println("接收客户端数据:" + body);
ByteBuf pingMessage = Unpooled.buffer();
pingMessage.writeBytes(req);
channelHandlerContext.writeAndFlush(pingMessage); //服务端使用这个就能向 每个连接上来的客户端群发消息
//NettyConfig.group.writeAndFlush(info);
// Iterator<Channel> iterator = NettyConfig.group.iterator();
// while(iterator.hasNext()){
// //打印出所有客户端的远程地址
// System.out.println((iterator.next()).remoteAddress());
// }
} }

使用网络调试助手进行连接测试 下载地址

https://www.wanpishe.top/detail?blogId=fc62fce2-020a-4815-8388-0903e4a54e1f

netty实现TCP长连接的更多相关文章

  1. 基于netty实现的长连接,心跳机制及重连机制

    技术:maven3.0.5 + netty4.1.33 + jdk1.8   概述 Netty是由JBOSS提供的一个java开源框架.Netty提供异步的.事件驱动的网络应用程序框架和工具,用以快速 ...

  2. 不仅仅是百万级TCP长连接框架 t-io

    t-io: 不仅仅是百万级TCP长连接框架 t-io是基于jdk aio实现的易学易用.稳定.性能强悍.将多线程运用到极致.内置功能丰富的即时通讯框架(广义上的即时通讯,并非指im),字母 t 寓意t ...

  3. Http 和TCP的关系,TCP长连接和短连接有什么区别?

    HTTP 协议即超文本传送协议(Hypertext Transfer Protocol ),是Web联网的基础,也是手机联网常用的协议之一,HTTP协议是建立在TCP协议之上的一种应用.由于HTTP在 ...

  4. TCP 长连接与短连接的区别

    TCP连接 当网络通信时采用TCP协议时,在真正的读写操作之前,server与client之间必须建立一个连接,当读写操作完成后,双方不再需要这个连接时它们可以释放这个连接,连接的建立是需要三次握手的 ...

  5. TCP长连接与短连接

    1.概念区别 所谓TCP短连接,是指通信双方有数据交互时,就建立一个TCP连接,数据发送完成后,则断开此TCP连接.也就是说TCP连接维持的时间比较短.一般银行网页数据交互都使用短连接.再比如说htt ...

  6. TCP长连接与短连接的区别

    http://www.cnblogs.com/liuyong/archive/2011/07/01/2095487.html 1. TCP连接 当网络通信时采用TCP协议时,在真正的读写操作之前,se ...

  7. 多进程解决datasnap支持的tcp长连接数量少的问题

    对于实时采集数据的项目,应用场景比如是这样的:5000客户端,每个客户端每隔500MS要给服务器上传一次数据. 大家知道,像INDY这种阻塞型的通信控件,所能支持的TCP长连接的一般地不能超过1000 ...

  8. TCP长连接与短连接的原理及区别

    一.当网络通信时采用TCP协议时:  1.过程: 第一步:(在真正的读写操作之前)Server 和Client 之间必须建立一个连接,连接的建立需要三次握手 经典的三次握手示意图: 第二步:进行读写操 ...

  9. [转载] TCP长连接与短连接的区别

    转载自http://www.cnblogs.com/liuyong/archive/2011/07/01/2095487.html 1. TCP连接 当网络通信时采用TCP协议时,在真正的读写操作之前 ...

随机推荐

  1. [JSOI2018]潜入行动 树形DP_复杂计数

    code #include <cstdio> #include <algorithm> #include <cstring> #include <string ...

  2. [转] -- html5手机网站自适应需要加的meta标签

    webapp开发初期,会碰到在pc端开发好的页面在移动端显示过大的问题,这里需要在html head中加入meta标签来控制缩放 <meta name=" viewport" ...

  3. [CEOI2007]树的匹配Treasury(树形DP+高精)

    题意 给一棵树,你可以匹配有边相连的两个点,问你这棵树的最大匹配时多少,并且计算出有多少种最大匹配. N≤1000,其中40%的数据答案不超过 108 题解 显然的树形DP+高精. 这题是作为考试题考 ...

  4. Unity 给FindGameObjectsWithTag排序

    GameObject[] patrol = GameObject.FindGameObjectsWithTag ("Player").OrderBy (g => g.tran ...

  5. Unity 如何将apk放到Android系统的system里

    有时我们需要用unity开发一款Android的系统软件,很坑,步骤如下: 1.用unity打包出来,签名. 2.用解压工具打开签过名的apk. 3.将lib里面的.so文件复制出来. 4.adb r ...

  6. 彻底解决lazarus安装组件后烦人的编译时单元找不到的问题!

    以安装indy为例 1/下载组件包, http://www.indyproject.org/Sockets/fpc/indy-10.2.0.3.zip 2/爆开放于C:\lazarus\compone ...

  7. BZOJ3511: 土地划分

    [传送门:BZOJ3511] 简要题意: 给出n个点,m条边,每个点有A和B两种形态,一开始1为A,n为B 给出VA[i]和VB[i],表示第i个点选择A和B形态的价值 每条边给出x,y,EA,EB, ...

  8. RPC和Socket

    RPC和Socket的区别 rpc是通过什么实现啊?socket! RPC(Remote Procedure Call,远程过程调用)是建立在Socket之上的,出于一种类比的愿望,在一台机器上运行的 ...

  9. cookies,sessionStorage和localStorage的区别

    共同点:都是保存在浏览器端,且同源的.区别:cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递.而sessionStorage和localStora ...

  10. word中添加Mathtype公式行间距改变问题

    转载链接:http://blog.sciencenet.cn/home.php?mod=space&uid=471807&do=blog&id=616838 最近碰到在word ...