netty传输文件示例代码,包括发送和接收
时间: 2023-05-20 18:07:37 浏览: 170
netty文件传输
以下是一个 Netty 传输文件的示例代码,包括发送和接收。这个示例代码使用 Java 语言编写,可以在 Windows、Linux 等各种操作系统上运行。
发送端的代码:
```java
import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import java.io.File;
import java.io.FileInputStream;
import java.util.concurrent.TimeUnit;
public class FileSender {
private String host;
private int port;
public FileSender(String host, int port) {
this.host = host;
this.port = port;
}
public void sendFile(String filePath) throws Exception {
final File file = new File(filePath);
Bootstrap b = new Bootstrap();
b.group(new NioEventLoopGroup())
.channel(NioSocketChannel.class)
.option(ChannelOption.TCP_NODELAY, true)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new StringEncoder(), new StringDecoder(), new FileSenderHandler(file));
}
});
ChannelFuture future = b.connect(host, port).sync();
future.channel().closeFuture().sync();
}
private class FileSenderHandler extends ChannelInboundHandlerAdapter {
private File file;
private FileInputStream fis;
public FileSenderHandler(File file) {
this.file = file;
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
String fileName = file.getName() + "\n";
String fileSize = String.valueOf(file.length()) + "\n";
ctx.writeAndFlush(Unpooled.copiedBuffer(fileName.getBytes()));
ctx.writeAndFlush(Unpooled.copiedBuffer(fileSize.getBytes()));
fis = new FileInputStream(file);
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if (msg instanceof String) {
String response = (String) msg;
if ("OK\n".equals(response)) { // 服务端已经准备好接收文件
byte[] buf = new byte[1024];
int len = 0;
while ((len = fis.read(buf)) != -1) {
ctx.writeAndFlush(Unpooled.copiedBuffer(buf, 0, len));
}
TimeUnit.MILLISECONDS.sleep(500); // 等待一段时间确保数据已经被发送完毕
ctx.close(); // 发送完毕后关闭 channel
} else { // 服务端出现错误
System.out.println("Server error: " + response);
ctx.close();
}
}
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
fis.close();
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
ctx.close();
}
}
public static void main(String[] args) throws Exception {
FileSender sender = new FileSender("127.0.0.1", 9090);
sender.sendFile("D:/test.zip");
}
}
```
接收端的代码:
```java
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import java.io.File;
import java.io.FileOutputStream;
public class FileReceiver {
private int port;
public FileReceiver(int port) {
this.port = port;
}
public void start() throws Exception {
ServerBootstrap b = new ServerBootstrap();
b.group(new NioEventLoopGroup())
.channel(NioServerSocketChannel.class)
.option(ChannelOption.SO_BACKLOG, 1024)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast(new StringEncoder(), new StringDecoder(), new FileReceiveHandler());
}
});
ChannelFuture future = b.bind(port).sync();
System.out.println("FileReceiver started and listening on " + port);
future.channel().closeFuture().sync();
}
private class FileReceiveHandler extends ChannelInboundHandlerAdapter {
private FileOutputStream fos;
private String fileName;
private long fileSize;
private long receivedSize;
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
if (msg instanceof String) {
String response = (String) msg;
if (fileName == null) {
fileName = response.trim();
return;
}
if (fileSize <= 0) {
fileSize = Long.parseLong(response.trim());
File file = new File("./" + fileName);
fos = new FileOutputStream(file);
ctx.writeAndFlush(Unpooled.copiedBuffer("OK\n".getBytes()));
return;
}
}
if (fos == null) {
System.out.println("FileReceiver error: invalid message received");
return;
}
byte[] data = (byte[]) msg;
fos.write(data); // 写入文件
receivedSize += data.length;
if (receivedSize == fileSize) { // 文件接收完成
fos.close();
System.out.println("FileReceiver: file " + fileName + " received, size=" + fileSize);
ctx.close(); // 关闭 channel
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
ctx.close();
}
}
public static void main(String[] args) throws Exception {
FileReceiver receiver = new FileReceiver(9090);
receiver.start();
}
}
```
这个示例代码中实现了一个简单的客户端和服务端,可以在两者之间传输文件。通过该示例代码,你可以学习到如何使用 Netty 实现文件传输。
阅读全文