netty 文件传输服务器,Netty之二进制文件传输

传输会话简要

客户端发起一个文本请求给服务器端, 服务器端解析里面文本, 返回文件给客户端, 客户端解析文件

99219b462d1fd02315547dbe0a026494.png

服务器端

因为示例文件比较小, 所以没有做分段传输, 而是直接一次性把整个文件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(

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 要在 Netty 中使用 WebSocket 传输图片,需要执行以下步骤: 1. 创建 WebSocket 服务端和客户端。 2. 在服务端处理器中,当收到新的 WebSocket 连接请求时,调用 `Channel.pipeline().addLast(new HttpObjectAggregator(65536))` 方法将 HTTP 消息聚合器添加到处理器链中。 3. 在客户端处理器中,当收到 WebSocket 握手响应消息时,调用 `Channel.pipeline().addLast(new HttpObjectAggregator(65536))` 方法将 HTTP 消息聚合器添加到处理器链中。 4. 在服务端处理器中,当收到 WebSocket 文本消息时,调用 `String encoded = Base64.getEncoder().encodeToString(bytes);` 将图片转换为 base64 编码的字符串。 5. 在客户端处理器中,当收到 WebSocket 文本消息时,调用 `byte[] decoded = Base64.getDecoder().decode(encoded);` 将 base64 编码的字符串转换为图片。 以下是一个简单的示例代码: ```java // 服务端代码 public class WebSocketServer { public static void main(String[] args) throws Exception { EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .childHandler(new WebSocketServerInitializer()); Channel ch = b.bind(8888).sync().channel(); ch.closeFuture().sync(); } finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } } class WebSocketServerInitializer extends ChannelInitializer<SocketChannel> { @Override public void initChannel(Socket ### 回答2: open jdk11: ```java import io.netty.bootstrap.ServerBootstrap; import io.netty.buffer.ByteBuf; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelOption; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.codec.http.*; import io.netty.handler.codec.http.websocketx.*; import io.netty.handler.stream.ChunkedWriteHandler; import io.netty.util.CharsetUtil; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.File; import java.nio.file.Files; public class NettyWebSocketImageServer { private final int port; public NettyWebSocketImageServer(int port) { this.port = port; } public void run() throws Exception { NioEventLoopGroup bossGroup = new NioEventLoopGroup(); NioEventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap b = new ServerBootstrap(); b.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer<SocketChannel>() { @Override public void initChannel(SocketChannel ch) { ch.pipeline().addLast(new HttpServerCodec()); ch.pipeline().addLast(new HttpObjectAggregator(64 * 1024)); ch.pipeline().addLast(new ChunkedWriteHandler()); ch.pipeline().addLast(new WebSocketServerProtocolHandler("/image")); ch.pipeline().addLast(new WebSocketImageHandler()); } }) .option(ChannelOption.SO_BACKLOG, 128) .childOption(ChannelOption.SO_KEEPALIVE, true); System.out.println("Server started"); b.bind(port).sync().channel().closeFuture().sync(); } finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } public static void main(String[] args) throws Exception { int port = 8080; NettyWebSocketImageServer server = new NettyWebSocketImageServer(port); server.run(); } public static class WebSocketImageHandler extends SimpleChannelInboundHandler<WebSocketFrame> { private static final String IMAGE_PATH = "path_of_your_image"; // Replace with actual image path @Override protected void channelRead0(ChannelHandlerContext ctx, WebSocketFrame frame) throws Exception { if (frame instanceof TextWebSocketFrame) { // Handle text frame String request = ((TextWebSocketFrame) frame).text(); System.out.println("Received request: " + request); // Load image and send as binary data File file = new File(IMAGE_PATH); if (file.exists() && file.isFile()) { byte[] imageBytes = Files.readAllBytes(file.toPath()); BufferedImage image = ImageIO.read(file); ByteArrayOutputStream baos = new ByteArrayOutputStream(); ImageIO.write(image, "jpg", baos); byte[] encodedImage = baos.toByteArray(); BinaryWebSocketFrame response = new BinaryWebSocketFrame(Unpooled.wrappedBuffer(encodedImage)); ctx.writeAndFlush(response); } } else if (frame instanceof CloseWebSocketFrame) { ctx.close(); } } @Override public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { cause.printStackTrace(); ctx.close(); } } } ``` 客户端代码: ```javascript const WebSocket = require('ws'); const fs = require('fs'); const ws = new WebSocket('ws://localhost:8080/image'); ws.on('open', function open() { ws.send('Please send the image'); }); ws.on('message', function incoming(data) { const buffer = new Uint8Array(data); fs.writeFileSync('receivedImage.jpg', buffer); }); ws.on('close', function close() { console.log('Connection closed'); }); ``` 这段代码创建了一个基于Netty的WebSocket服务器和一个WebSocket客户端。服务器使用8080端口监听WebSocket连接,当接收到客户端发送的请求后,会读取特定路径下的图片并将二进制数据发送到客户端。 JavaScript的WebSocket客户端会连接到服务器,并发送"Please send the image"消息。当客户端接收到服务器发送的数据后,会将收到的二进制数据写入本地磁盘上的"receivedImage.jpg"文件中。 请注意替换服务器代码中的图片路径为实际的图片路径。 ### 回答3: netty是一个高效、可扩展、异步事件驱动的网络应用框架,它提供了对TCP和UDP传输协议的支持,并且还支持HTTP和WebSocket等高层协议。下面是一个使用netty实现WebSocket传输图片的示例代码: ```java 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.ChannelPipeline; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.channel.nio.NioEventLoopGroup; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.codec.http.HttpObjectAggregator; import io.netty.handler.codec.http.HttpRequest; import io.netty.handler.codec.http.HttpRequestDecoder; import io.netty.handler.codec.http.HttpResponseEncoder; import io.netty.handler.stream.ChunkedWriteHandler; import io.netty.handler.codec.http.websocketx.WebSocketFrame; import io.netty.handler.codec.http.websocketx.WebSocketFrameDecoder; import io.netty.handler.codec.http.websocketx.WebSocketFrameEncoder; import io.netty.handler.codec.http.websocketx.WebSocketHandshakeException; import io.netty.handler.codec.http.websocketx.WebSocketServerHandshaker; import io.netty.handler.codec.http.websocketx.WebSocketServerHandshakerFactory; import io.netty.handler.codec.http.websocketx.BinaryWebSocketFrame; import io.netty.handler.codec.http.websocketx.TextWebSocketFrame; import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler; public class WebSocketServer { public static void main(String[] args) throws InterruptedException { NioEventLoopGroup bossGroup = new NioEventLoopGroup(); NioEventLoopGroup workerGroup = new NioEventLoopGroup(); try { ServerBootstrap serverBootstrap = new ServerBootstrap(); serverBootstrap.group(bossGroup, workerGroup) .channel(NioServerSocketChannel.class) .childHandler(new ChannelInitializer<SocketChannel>() { protected void initChannel(SocketChannel ch) throws Exception { ChannelPipeline pipeline = ch.pipeline(); pipeline.addLast(new HttpRequestDecoder()); pipeline.addLast(new HttpObjectAggregator(65536)); pipeline.addLast(new HttpResponseEncoder()); pipeline.addLast(new ChunkedWriteHandler()); pipeline.addLast(new WebSocketServerProtocolHandler("/websocket")); pipeline.addLast(new WebSocketFrameDecoder()); pipeline.addLast(new WebSocketFrameEncoder()); pipeline.addLast(new SimpleChannelInboundHandler<WebSocketFrame>() { protected void channelRead0(ChannelHandlerContext ctx, WebSocketFrame frame) throws Exception { if (frame instanceof BinaryWebSocketFrame) { BinaryWebSocketFrame binaryFrame = (BinaryWebSocketFrame) frame; // 在这里处理接收到的二进制图片数据 // ... } } public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception { if (evt instanceof HttpRequest) { HttpRequest request = (HttpRequest) evt; WebSocketServerHandshakerFactory factory = new WebSocketServerHandshakerFactory("ws://localhost:8080/websocket", null, false); WebSocketServerHandshaker handshaker = factory.newHandshaker(request); if (handshaker == null) { WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ctx.channel()); } else { try { handshaker.handshake(ctx.channel(), request); } catch (WebSocketHandshakeException e) { e.printStackTrace(); } } } } }); } }); ChannelFuture channelFuture = serverBootstrap.bind(8080).sync(); channelFuture.channel().closeFuture().sync(); } finally { bossGroup.shutdownGracefully(); workerGroup.shutdownGracefully(); } } } ``` 上述示例代码创建了一个WebSocket服务器,在端口8080上监听传入的WebSocket连接。当接受到二进制的WebSocket帧时,通过`channelRead0`方法进行图片数据的接收和处理。 请注意,以上只是一个简化的示例,实际上在处理图片数据时可能需要进行一些额外的处理,比如解码、保存等,具体情况需要根据自己的需求进行适当的修改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值