netty 文件传输服务器,Netty之二进制文件传输
传输会话简要
客户端发起一个文本请求给服务器端, 服务器端解析里面文本, 返回文件给客户端, 客户端解析文件
服务器端
因为示例文件比较小, 所以没有做分段传输, 而是直接一次性把整个文件byte[]都发给客户端了.
如果需要传输大文件, 则需要做粘包拆包, 参考另外一篇博文 Netty之粘包分包
需要三个ChannelPipeline
// 解析客户端发送的文本json
pipeline.addLast(new StringDecoder());
// 二进制文件加密传输
pipeline.addLast(new ObjectEncoder());
// 业务逻辑
pipeline.addLast(new FileServerHandler());
FileServerHandler业务逻辑
// 获取到客户端请求, 解析path, 返回二进制文件
JSONObject jo = new JSONObject(msg.toString());
if (StringUtils.isNotEmpty(jo.optString("path"))) {
PDFContent pdf = new PDFContent();
byte[] content = com.fr.general.IOUtils.inputStream2Bytes(new FileInputStream(jo.optString("path")));
pdf.setContent(content);
ctx.writeAndFlush(pdf);
} else {
System.out.println(jo.optString("res"));
}
客户端
跟服务器端对应的三个ChannelPipeline
// 传输文本给服务器端
p.addLast(new StringEncoder());
// 二进制文件获取解析
p.addLast(new ObjectDecoder(ClassResolvers.cacheDisabled(this
.getClass().getClassLoader())));
// 客户端业务代码
p.addLast(new FileClientHandler());
FileClientHandler业务逻辑
@Override
public void channelActive(ChannelHandlerContext ctx) {
try {
// 将要获取的pdf路径发送给服务器端
JSONObject jo = JSONObject.create().put("path", "d:\\a.pdf");
ctx.writeAndFlush(jo.toString());
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
PDFContent content = (PDFContent) msg;
// 从服务器端获取的二进制文件存到本地
String fileName = UUID.randomUUID().toString() + ".pdf";
File file = new File("D:\\" + fileName);
try {
FileOutputStream out = new FileOutputStream(file);
IOUtils.copyBinaryTo(new ByteArrayInputStream(content.getContent()), out);
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
JSONObject jo = JSONObject.create().put("res", "Thank You, I Have The File!");
ctx.writeAndFlush(jo.toString());
ctx.close();
} catch (JSONException e) {
e.printStackTrace();
}
}
完整的代码如下
FileClient & FileClientHandler
package test;
import com.fr.general.IOUtils;
import com.fr.json.JSONException;
import com.fr.json.JSONObject;
import com.fr.stable.core.UUID;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.serialization.ClassResolvers;
import io.netty.handler.codec.serialization.ObjectDecoder;
import io.netty.handler.codec.string.StringEncoder;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileClient {
public FileClient(){
}
public void start() {
EventLoopGroup group = new NioEventLoopGroup();
try {
Bootstrap bootstrap = new Bootstrap();
bootstrap.group(group)
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer() {
@Override
protected void initChannel(SocketChannel s) throws Exception {
ChannelPipeline p = s.pipeline();
// 传输文本给服务器端
p.addLast(new StringEncoder());
// 二进制文件获取解析
p.addLast(new ObjectDecoder(ClassResolvers.cacheDisabled(this
.getClass().getClassLoader())));
// 客户端业务代码
p.addLast(new FileClientHandler());
}
});
ChannelFuture future = bootstrap.connect("localhost", 7766).sync();
future.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
group.shutdownGracefully();
}
}
public static void main(String[] args) throws InterruptedException {
new FileClient().start();
}
private static class FileClientHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelActive(ChannelHandlerContext ctx) {
try {
// 将要获取的pdf路径发送给服务器端
JSONObject jo = JSONObject.create().put("path", "d:\\a.pdf");
ctx.writeAndFlush(jo.toString());
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
PDFContent content = (PDFContent) msg;
// 从服务器端获取的二进制文件存到本地
String fileName = UUID.randomUUID().toString() + ".pdf";
File file = new File("D:\\" + fileName);
try {
FileOutputStream out = new FileOutputStream(file);
IOUtils.copyBinaryTo(new ByteArrayInputStream(content.getContent()), out);
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
JSONObject jo = JSONObject.create().put("res", "Thank You, I Have The File!");
ctx.writeAndFlush(jo.toString());
ctx.close();
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
ctx.close();
}
}
}
FileServer & FileServerHandler
package test;
import com.fr.json.JSONObject;
import com.fr.stable.StringUtils;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
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.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.serialization.ObjectEncoder;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import java.io.FileInputStream;
public class FileServer {
private FileServer() {
startServer();
}
private void startServer() {
EventLoopGroup bossGroup = new NioEventLoopGroup(1);
EventLoopGroup workerGroup = new NioEventLoopGroup();
try{
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap.group(bossGroup, workerGroup)
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 100)
.handler(new LoggingHandler(LogLevel.INFO))
.childHandler(new ChannelInitializer() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ChannelPipeline pipeline = ch.pipeline();
// 解析客户端发送的文本json
pipeline.addLast(new StringDecoder());
// 二进制文件加密传输
pipeline.addLast(new ObjectEncoder());
// 业务逻辑
pipeline.addLast(new FileServerHandler());
}
});
ChannelFuture future = bootstrap.bind("localhost", 7766).sync();
future.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
bossGroup.shutdownGracefully();
workerGroup.shutdownGracefully();
}
}
private class FileServerHandler extends ChannelInboundHandlerAdapter {
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
// 获取到客户端请求, 解析path, 返回二进制文件
JSONObject jo = new JSONObject(msg.toString());
if (StringUtils.isNotEmpty(jo.optString("path"))) {
PDFContent pdf = new PDFContent();
byte[] content = com.fr.general.IOUtils.inputStream2Bytes(new FileInputStream(jo.optString("path")));
pdf.setContent(content);
ctx.writeAndFlush(pdf);
} else {
System.out.println(jo.optString("res"));
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
cause.printStackTrace();
ctx.close();
}
}
public static void main(String[] args){
// 启动Server
new FileServer();
}
}
PDFContent
package test;
import java.io.Serializable;
/**
* 文件的封装
*/
public class PDFContent implements Serializable{
private byte[] content;
public byte[] getContent() {
return content;
}
public void setContent(byte[] content) {
this.content = content;
}
}
[netty4][netty-transport]netty之nio传输层
[netty4][netty-transport]netty之nio传输层 nio基本处理逻辑 查看这里 Selector的处理 Selector实例构建 NioEventLoop.openSelec ...
WebService之Axis2(4):二进制文件传输
在中讲过,如果要传递二进制文件(如图像.音频文件等),可以使用byte[]作为数据类型进行传递,然后客户端使用RPC方式 ...
netty中的传输
终于在课设的闲时间把netty实战的四五章给解决了 这里来记录一下第四章里面所讲的IO 首先说到IO,我想,必须要先了解阻塞,非阻塞,同步和异步这四个词 看到一个讲的很易懂的例子:https://ww ...
Netty 框架学习 —— 传输
概述 流经网络的数据总是具有相同的类型:字节,这些字节如何传输主要取决于我们所说的网络传输.用户并不关心传输的细节,只在乎字节是否被可靠地发送和接收 如果使用 Java 网络编程,你会发现,某些时候当 ...
netty的对象传输
pom
netty 对象序列化传输示例
package object.server.impl; import io.netty.bootstrap.ServerBootstrap; import io.netty.channel.Chann ...
Netty进行文件传输
本次是利用TCP在客户端发送文件流,服务端就接收流,写入相应的文件. 实验的源文件是一个图片,假设地址是D:\\Koala.jpg,接收保存后的图片为D:\\test.jpg 原理就是将文件读取成by ...
【Netty】Netty传输
一.前言 在简单学习了Netty中的组件后,接着学习Netty中数据的传输细节. 二.传输 2.1 传输示例 Netty中的数据传输都是使用的字节类型,下面通过一个实例进行说明,该实例中服务器接受请求 ...
Netty实战四之传输
流经网络的数据总是具有相同的类型:字节(网络传输——一个帮助我们抽象底层数据传输机制的概念) Netty为它所有的传输实现提供了一个通用的API,即我们可以将时间花在其他更有成效的事情上. 我们将通过 ...
随机推荐
iOS 运行时
1.点击每一个cell都要跳转到一个控制器,swich会很麻烦,那么可以用运行时来进行跳转. a. 定义一个数组用来存放控制器的名字 - (NSArray *)controllerArr{ if (_ ...
hdu 4876(剪枝+暴力)
题意:给定n,k,l,接下来给出n个数,让你从n个数中选取k个数围成一圈,然后从这k个数中随意选出连续的m(m>=1&&m<=k)个数进行异或后得到[l,r]区间的所有值, ...
TCP/IP协议三次握手与四次握手流程解析(转载及总结)
netty 文件传输服务器,Netty之二进制文件传输相关推荐
- FJ集团企业级邮件服务器——Exchange服务器安装与配置(边缘传输服务器)
简单就是力量(power cloaked in simplicity)! Exchange边缘传输服务器角色通常部署在组织外围网络中,它能够最小化攻击面,还可以处理所有面向Internet的邮件流,为 ...
- 【Netty】五、Netty实现Http服务器
Netty实现http服务器 一.Netty实现hhttp服务器 代码演示 HttpServer HttpServerHandler HttpServerInitializer (http请求解码和编 ...
- ios如何上传文件到服务器,ios通过ftp上传文件到服务器
ios通过ftp上传文件到服务器 内容精选 换一换 华为云帮助中心,为用户提供产品简介.价格说明.购买指南.用户指南.API参考.最佳实践.常见问题.视频帮助等技术文档,帮助您快速上手使用华为云服务. ...
- ftp ios 上传文件到服务器上,ios通过ftp上传文件到服务器
ios通过ftp上传文件到服务器 内容精选 换一换 华为云帮助中心,为用户提供产品简介.价格说明.购买指南.用户指南.API参考.最佳实践.常见问题.视频帮助等技术文档,帮助您快速上手使用华为云服务. ...
- Linux平台基于socket的文件传输服务器和客户端
Linux平台基于socket的文件传输服务器和客户端 目录 前言 一.服务器程序结构 二.客户程序结构 三.代码 1.服务器主程序video_serv_fork.c 2.服务器子程序video_tr ...
- 文件传输:二进制文件传输与文本传输(file transfer)
一种文件传输(text transfer)方式,其中文件的每一比特(bit)都照样传输,与文本传输(file transfer)相对(在文本传输中,文本被转换为接收方机器需要的任一种格式). 值得注意 ...
- java如何实现tcp传输图像_如何在java中实现TCP服务器和TCP客户端传输文件
我实现了简单的TCP服务器和TCP客户端类,可以从客户端发送消息到服务器,消息将在服务器端转换为大写,但是如何实现从服务器到客户端的传输文件,并从客户端上传文件到服务器.以下代码是我所得到的. TCP ...
- 文件传输服务器的默认端口,服务器上传文件端口
服务器上传文件端口 内容精选 换一换 华为云帮助中心,为用户提供产品简介.价格说明.购买指南.用户指南.API参考.最佳实践.常见问题.视频帮助等技术文档,帮助您快速上手使用华为云服务. 安装传输工具 ...
- 登录文件传输服务器,生信小技巧之:在本地与服务器间快速传输文件,无密码登录远端服务器...
今天是五一节,首先祝各位粉丝节日快乐,虽然是假期,但是我们推文还是不会停,但相信大家都不愿意看太过难太过复杂的推文,没问题.今天和大家分享一些简单但很实用的干货,保证每个生信小白都会获益,嘿嘿嘿. 作 ...
最新文章
- java编写数字金字塔_用JAVA写数字金字塔
- Linux /etc/init.d目录
- php中isdefin,在PHP中定義全局常量數組的最“優雅”方法是什么
- windows server 2003中 如何限制用户修改计算机名,Windows命令行下修改文件访问控制权限 -电脑资料...
- node.js 安装使用http-server
- form的enctype和action
- Golang笔记—封装/继承/接口
- opencv_找cv::Mat中的最大值和最小值
- Java后端技术知识点汇总(思维导图)
- leapftp download,leapftp download如何下载,软件介绍
- 阿里云服务器linux 启动网卡失败,提示does not seem to be present,delaying initialization
- (load和initialize)不要被你的log迷惑了你对问题的判断
- 从Mac的GUID分区谈起
- Ant design vue pro 添加多页签
- IOS获取屏幕分辨率
- android现状及发展趋势,2021年Android手机现状分析
- BlueTeam 应急
- kohana php版本,kohana框架的入门学习 2.0版本的
- idea git 日常使用
- 2019-2020记罗振宇“时间的朋友”跨年演讲(一)
热门文章
- AtomicInteger源码注释
- CI框架 -- 网页缓存
- zabbix企业应用之报表功能
- 单元测试:使用mocha和should.js搭建nodejs的单元测试
- CMake一次失败应用
- nagios视频教程【原创】
- python3 filter 列表元素过滤(匹配)用法
- centos7 tomcat 设置开机启动
- linux 开机错误 Entering emergency mode. Exit the shell to continue.
- mysql 加密方式 caching_sha2_password 和 mysql_native_password 说明