服务端:

package com.server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
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.nio.NioServerSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder; /**
* netty5版本服务端
*/
public class Server { public static void main(String[] args) {
//服务类
ServerBootstrap bootstrap = new ServerBootstrap(); //boss和worker, netty5不是线程池,而是事件循环组,里面包含线程池。
EventLoopGroup boss = new NioEventLoopGroup();
EventLoopGroup worker = new NioEventLoopGroup(); try {
//设置线程池
bootstrap.group(boss, worker);//boss用来监听端口的 //设置socket工厂、
bootstrap.channel(NioServerSocketChannel.class); //设置管道工厂
bootstrap.childHandler(new ChannelInitializer<Channel>() { @Override
protected void initChannel(Channel ch) throws Exception {
ch.pipeline().addLast(new StringDecoder());
ch.pipeline().addLast(new StringEncoder());
ch.pipeline().addLast(new ServerHandler());
}
}); //netty3中对应设置如下
//bootstrap.setOption("backlog", 1024);
//bootstrap.setOption("tcpNoDelay", true);
//bootstrap.setOption("keepAlive", true);
//设置参数,TCP参数
bootstrap.option(ChannelOption.SO_BACKLOG, 2048);//serverSocketchannel的设置,链接缓冲池的大小。tcp的服务端是有队列的。队列保存2048个客户端。2048后面的连接是拒绝的。
bootstrap.childOption(ChannelOption.SO_KEEPALIVE, true);//socketchannel的设置,维持链接的活跃,清除死链接
bootstrap.childOption(ChannelOption.TCP_NODELAY, true);//socketchannel的设置,关闭延迟发送。发一包并不是马上发出去,而是积累到一定之后再发出去。 //绑定端口
ChannelFuture future = bootstrap.bind(10101); System.out.println("start"); //等待服务端关闭
future.channel().closeFuture().sync(); } catch (Exception e) {
e.printStackTrace();
} finally{
//释放资源
boss.shutdownGracefully();
worker.shutdownGracefully();
}
}
}
package com.server;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
/**
* 服务端消息处理
*/
public class ServerHandler extends SimpleChannelInboundHandler<String> { @Override
protected void messageReceived(ChannelHandlerContext ctx, String msg) throws Exception {
System.out.println(msg);
ctx.channel().writeAndFlush("hi");
ctx.writeAndFlush("hi");
} /**
* 新客户端接入
*/
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("channelActive");
} /**
* 客户端断开
*/
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
System.out.println("channelInactive");
} /**
* 异常
*/
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
} }

客户端:

package com.client;

import java.io.BufferedReader;
import java.io.InputStreamReader; import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
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.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder; /**
* netty5版本的客户端
*/
public class Client { public static void main(String[] args) {
//服务类
Bootstrap bootstrap = new Bootstrap();
//worker
EventLoopGroup worker = new NioEventLoopGroup();//boss用来监听端口,这里只创建worker
try {
//设置线程池
bootstrap.group(worker);
//设置socket工厂、
bootstrap.channel(NioSocketChannel.class);
//设置管道
bootstrap.handler(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(Channel ch) throws Exception {
ch.pipeline().addLast(new StringDecoder());
ch.pipeline().addLast(new StringEncoder());
ch.pipeline().addLast(new ClientHandler());
}
});
ChannelFuture connect = bootstrap.connect("127.0.0.1", 10101);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
while(true){
System.out.println("请输入:");
String msg = bufferedReader.readLine();
connect.channel().writeAndFlush(msg);
}
} catch (Exception e) {
e.printStackTrace();
} finally{
worker.shutdownGracefully();
}
}
}
package com.client;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
/**
* 客户端消息处理
*/
public class ClientHandler extends SimpleChannelInboundHandler<String> {
@Override
protected void messageReceived(ChannelHandlerContext ctx, String msg) throws Exception {
System.out.println("客户端收到消息:"+msg);
} }

一个客户端启动多个连接:

package com.client;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger; import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
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.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder; /**
多连接客户端,客户端保持一个连接不够,要保持多个连接。 线程池是有多个线程,每个线程里面有一个任务队列,线程run的时候会从任务队列取一个任务出来,执行任务的run方法,
队列里面没有任务就阻塞等待新的任务进来。 一个thread + 队列 == 一个单线程线程池 =====> 线程安全的,任务是线性串行执行的 对象池:首先初始化n个对象,把这些对象放入一个队列里面,需要对象的时候会出栈一个对象,有对象就出栈,使用完了归还对象池里面。
没有对象会阻塞等待有可用的对象。或者创建一个新的对象使用完之后归还线程池,归还的时候如果池子满了就销毁。
比如数据库连接池:使用完后要释放资源,就是把连接放回连接池里面。 对象组:首先初始化n个对象,把这些对象放入一个数组里面。使用的时候获取一个对象不移除,使用完之后不用归还。需要对象有并发的能力。 对象组:线程安全,不会产生阻塞效应
对象池:线程不安全,会产生阻塞效应
*/
public class MultClient { /**
* 服务类
*/
private Bootstrap bootstrap = new Bootstrap(); /**
* 会话,多个channel,
*/
private List<Channel> channels = new ArrayList<>(); /**
* 引用计数
*/
private final AtomicInteger index = new AtomicInteger(); /**
* 初始化
* @param count
*/
public void init(int count){ //worker
EventLoopGroup worker = new NioEventLoopGroup(); //设置线程池
bootstrap.group(worker); //设置socket工厂、
bootstrap.channel(NioSocketChannel.class); //设置管道
bootstrap.handler(new ChannelInitializer<Channel>() { @Override
protected void initChannel(Channel ch) throws Exception {
ch.pipeline().addLast(new StringDecoder());
ch.pipeline().addLast(new StringEncoder());
ch.pipeline().addLast(new ClientHandler());
}
}); for(int i=1; i<=count; i++){
ChannelFuture future = bootstrap.connect("192.168.0.103", 10101);
channels.add(future.channel());
}
} /**
* 获取会话
*/
public Channel nextChannel(){
return getFirstActiveChannel(0);
} private Channel getFirstActiveChannel(int count){
Channel channel = channels.get(Math.abs(index.getAndIncrement() % channels.size()));
if(!channel.isActive()){
//重连
reconnect(channel);
if(count >= channels.size()){
throw new RuntimeException("no can use channel");
}
return getFirstActiveChannel(count + 1);
}
return channel;
} /**
* 重连
* @param channel
*/
private void reconnect(Channel channel){
synchronized(channel){
if(channels.indexOf(channel) == -1){//已经重连过了
return ;
}
Channel newChannel = bootstrap.connect("192.168.0.103", 10101).channel();
channels.set(channels.indexOf(channel), newChannel);
}
}
}
package com.client;

import java.io.BufferedReader;
import java.io.InputStreamReader;
/**
* 启动类
*/
public class Start { public static void main(String[] args) { MultClient client = new MultClient();
client.init(5);//初始化5个连接
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
while(true){
try {
System.out.println("请输入:");
String msg = bufferedReader.readLine();
client.nextChannel().writeAndFlush(msg);
} catch (Exception e) {
e.printStackTrace();
}
}
} }

netty4----netty5的客户端和服务端的更多相关文章

  1. Netty4 学习笔记之二:客户端与服务端心跳 demo

    前言 在上一篇Netty demo 中,了解了Netty中的客户端和服务端之间的通信.这篇则介绍Netty中的心跳. 之前在Mina 中心跳的使用是通过继承 KeepAliveMessageFacto ...

  2. netty-4.客户端与服务端心跳

    (原) 第四篇,客户端与服务端心跳 心跳事件有三种,读空闲,写空闲,读写空闲,定义在了IdleState枚举类中,分别为READER_IDLE,WRITER_IDLE,ALL_IDLE 服务端: ma ...

  3. java客户端与服务端交互通用处理 框架解析

    一.综述 java 客户端与服务端交互过程中,采用NIO通讯是异步的,客户端基本采用同一处理范式,来进行同异步的调用处理. 处理模型有以下几个要素: 1. NIO发送消息后返回的Future 2. 每 ...

  4. java 从零开始手写 RPC (03) 如何实现客户端调用服务端?

    说明 java 从零开始手写 RPC (01) 基于 socket 实现 java 从零开始手写 RPC (02)-netty4 实现客户端和服务端 写完了客户端和服务端,那么如何实现客户端和服务端的 ...

  5. TCP学习之五:客户端、服务端异步传输字符串

    参考学习张子阳大神的博客:http://www.cnblogs.com/JimmyZhang/category/101698.html 消息发送接口: 消息接收接口: 客户端: 服务端: 消息发送类: ...

  6. TCP学习之三:客户端、服务端同步传输字符串

    参考学习张子阳大神的博客:http://www.cnblogs.com/JimmyZhang/category/101698.html 一个客户端.发送一条消息 客户端: 服务端: 注意:Networ ...

  7. 客户端向服务端传送特殊字符解决方法(检测到有潜在危险的 Request.Form 值)

    当客户端向服务端传输特殊字符时报错,错误信息如下图:

  8. [Java]Hessian客户端和服务端代码例子

    简要说明:这是一个比较简单的hessian客户端和服务端,主要实现从客户端发送指定的数据量到服务端,然后服务端在将接收到的数据原封不动返回到客户端.设计该hessian客户端和服务端的初衷是为了做一个 ...

  9. SignalR 实现web浏览器客户端与服务端的推送功能

    SignalR 是一个集成的客户端与服务器库,基于浏览器的客户端和基于 ASP.NET 的服务器组件可以借助它来进行双向多步对话. 换句话说,该对话可不受限制地进行单个无状态请求/响应数据交换:它将继 ...

  10. Fresco 源码分析(二) Fresco客户端与服务端交互(3) 前后台打通

    4.2.1.2.4 PipelineDraweeControllerBuilder.obtainController()源码分析 续 上节中我们提到两个核心的步骤 obtainDataSourceSu ...

随机推荐

  1. 【VBA】合并多个excel文件

    From http://www.zhihu.com/question/20366713 VBA代码如下: Sub 工作薄间工作表合并() Dim FileOpen Dim X As Integer A ...

  2. 《转》最受欢迎的ASP.NET的CMS下载

    1. Umbraco 项目地址 | 下载 Umbraco是一个开放源码的CMS内容管理系统,基于asp.net建立,使用mssql进行存储数据. 使用Umbraco ,设计师能创造出有效的XHTML标 ...

  3. Kotlin——中级篇(二): 属性与字段详解

    在前面的章节中,详细的为大家讲解到了Kotlin中对类的类的定义.使用.初始化.初始化.类继承等内容,但是在一个类中,几乎上是不可能不出现属性与字段(field)的,这一篇文章就为大家奉上Kotlin ...

  4. ios 统一设计,iOS6也玩扁平化

    转:http://esoftmobile.com/2014/01/14/build-ios6-ios7-apps/ 前言 前段时间,苹果在它的开发者网站上放出了iOS系统安装比例,其中iOS7占到78 ...

  5. css 横线中间添加文字

      demoline01.02选一个用足够了 <style> .demo_line_01 { width: 200px;/*这指的是文字的宽度*/ padding: 0 20px 0; m ...

  6. Jupyter Notebook远程服务器配置

    首先要生成密码,打开python终端. In [1]: from IPython.lib import passwd In [2]: passwd() Enter password: Verify p ...

  7. Visual Assist X助手的一些使用技巧和快捷键

    部分快捷键 Shift+Alt+F // Find References 查找引用 Shift+Alt+S // FindSynbolDialog打开查找符号对话框 Alt+G // GotoImpl ...

  8. Powershell计算时间间隔(New-TimeSpan)

    在Windows PowerShell里New-TimeSpan cmdlet提供了一种方法做日期算法. 计算时间间隔: 这个命令告诉你今天的日期与2006年除夕之间的天数: New-TimeSpan ...

  9. Access导入Sql 2008 R2 错误 0xc020801c

    在选择数据源界面: 数据源:Microsoft Access 文件名:选择要导入的文件 用户名:admin 密码:(空的) 猛击”高级“按钮 切到”高级“选项卡,访问权限设为 ReadWrite,去掉 ...

  10. http://element.eleme.io/#/zh-CN/component/quickstart

    http://element.eleme.io/#/zh-CN/component/quickstart