1.服务端
1.1 字符消息
public class NettyServer {
private static final int PORT = 8080;
public static void main(String[] args) throws Exception {
new ServerBootstrap()
.group(new NioEventLoopGroup(), new NioEventLoopGroup())
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<NioSocketChannel>() {
@Override
protected void initChannel(NioSocketChannel ch) throws Exception {
ch.pipeline().addLast(new StringDecoder());
ch.pipeline().addLast(new StringEncoder());
ch.pipeline().addLast(new ServerHandler());
}
})
.option(ChannelOption.SO_BACKLOG, 128)
.childOption(ChannelOption.SO_KEEPALIVE, true)
.bind(PORT);
}
}
public class ServerHandler extends SimpleChannelInboundHandler<Object> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, Object msg) {
try {
if (msg instanceof String) {
System.out.println("服务端接受信息:");
System.out.println(msg);
ctx.writeAndFlush("Server response: " + msg);
}
} catch (Exception e) {
e.printStackTrace();
ctx.close();
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws IOException {
cause.printStackTrace();
ctx.close();
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
System.out.println("Client disconnected");
super.channelInactive(ctx);
ctx.close();
}
}
1.2 文件
public class NettyServerFile {
private static final int PORT = 8081;
public static void main(String[] args) throws Exception {
new ServerBootstrap()
.group(new NioEventLoopGroup(), new NioEventLoopGroup())
.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<NioSocketChannel>() {
@Override
protected void initChannel(NioSocketChannel ch) throws Exception {
ch.pipeline().addLast(new ObjectDecoder(Integer.MAX_VALUE, ClassResolvers.weakCachingConcurrentResolver(null)));
ch.pipeline().addLast(new ObjectEncoder());
ch.pipeline().addLast(new ServerHandlerFile());
}
})
.option(ChannelOption.SO_BACKLOG, 128)
.childOption(ChannelOption.SO_KEEPALIVE, true)
.bind(PORT);
}
}
public class ServerHandlerFile extends ChannelInboundHandlerAdapter {
private int byteRead;
private volatile int start = 0;
private String file_dir = "C:\\Users\\liu.wenxuan1\\Desktop";
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
try {
System.out.println("接收到客户端信息");
if (msg instanceof FileUploadFile) {
System.out.println("\"文件上传中...");
FileUploadFile ef = (FileUploadFile) msg;
byte[] bytes = ef.getBytes();
System.out.println("byteRead:" + bytes.length);
byteRead = ef.getEndPos();
String md5 = ef.getFile_md5();
String path = file_dir + File.separator + md5;
File file = new File(path);
RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw");
randomAccessFile.seek(start);
randomAccessFile.write(bytes);
start = start + byteRead;
if (byteRead > 0) {
ctx.writeAndFlush(start);
}
System.out.println("文件已经读完--------" + byteRead);
randomAccessFile.close();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
ctx.close();
}
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
ctx.close();
}
}
public class FileUploadFile implements Serializable {
private static final long serialVersionUID = 1L;
private File file;
private String file_md5;
private int starPos;
private byte[] bytes;
private int endPos;
public int getStarPos() {
return starPos;
}
public void setStarPos(int starPos) {
this.starPos = starPos;
}
public int getEndPos() {
return endPos;
}
public void setEndPos(int endPos) {
this.endPos = endPos;
}
public byte[] getBytes() {
return bytes;
}
public void setBytes(byte[] bytes) {
this.bytes = bytes;
}
public File getFile() {
return file;
}
public void setFile(File file) {
this.file = file;
}
public String getFile_md5() {
return file_md5;
}
public void setFile_md5(String file_md5) {
this.file_md5 = file_md5;
}
}
2.客户端
@RestController
@RequestMapping("/netty")
public class NettyController {
@Autowired
private NettyClient nettyClient;
@PostMapping(value = "/sendMessage", consumes = "text/plain")
@ResponseBody
public void uploadFile(@RequestBody Stringmessage) {
try {
nettyClient.sendMessage(message);
} catch (Exception e) {
e.printStackTrace();
}
}
@PostMapping("/upload")
public void uploadFile(@RequestBody FileUploadFile uploadFile) {
try {
nettyClient.uploadFile(uploadFile);
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Data
public class FileUploadFile implements Serializable {
private static final long serialVersionUID = 1L;
private String filePath;
private File file;
private String fileName;
private int starPos;
private byte[] bytes;
private int endPos;
}
public class ClientHandler extends SimpleChannelInboundHandler<Object> {
@Override
protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
if (msg instanceof String) {
System.out.println("Client received: " + msg);
}
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("Client active");
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws IOException {
cause.printStackTrace();
ctx.close();
}
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
super.channelInactive(ctx);
}
}
public class ClientHandlerFile extends ChannelInboundHandlerAdapter {
private int byteRead;
private volatile int start = 0;
private volatile int lastLength = 0;
public RandomAccessFile randomAccessFile;
private FileUploadFile fileUploadFile = new FileUploadFile();
public ClientHandlerFile() {
}
public void send(FileUploadFile file, Channel ctx) {
try {
randomAccessFile = new RandomAccessFile(file.getFile(), "r");
randomAccessFile.seek(file.getStarPos());
lastLength = (int) randomAccessFile.length() ;
System.out.println("文件长度:" + randomAccessFile.length());
byte[] bytes = new byte[lastLength];
if ((byteRead = randomAccessFile.read(bytes)) != -1) {
file.setEndPos(byteRead);
file.setBytes(bytes);
ctx.writeAndFlush(file);
System.out.println("已发送");
} else {
System.out.println("文件已经读完");
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException i) {
i.printStackTrace();
}
}
@Override
public void channelActive(ChannelHandlerContext ctx) {
System.out.println("已连接");
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
}
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
cause.printStackTrace();
ctx.close();
}
}
@Component
public class NettyClient {
private static final int MESSAGE_PORT = 8080;
private static final int FILE_PORT = 8081;
private static final String HOST = "10.82.224.183";
private static final String PREFIX = "C:\\Users\\p30019551244\\Desktop\\";
public void sendMessage(String message) throws Exception {
new Bootstrap()
.group(new NioEventLoopGroup())
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<NioSocketChannel>() {
@Override
protected void initChannel(NioSocketChannel ch) throws Exception {
ch.pipeline().addLast(new StringDecoder());
ch.pipeline().addLast(new StringEncoder());
ch.pipeline().addLast(new ClientHandler());
}
})
.connect(HOST, MESSAGE_PORT)
.sync()
.channel()
.writeAndFlush(message);
}
public void uploadFile(FileUploadFile fileUploadFile) throws Exception {
Channel channel = new Bootstrap()
.group(new NioEventLoopGroup())
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<NioSocketChannel>() {
@Override
protected void initChannel(NioSocketChannel ch) throws Exception {
ch.pipeline().addLast(new ObjectDecoder(Integer.MAX_VALUE, ClassResolvers.weakCachingConcurrentResolver(null)));
ch.pipeline().addLast(new ObjectEncoder());
ch.pipeline().addLast(new ClientHandlerFile());
}
})
.connect(HOST, FILE_PORT)
.sync()
.channel();
fileUploadFile.setFile(new File(PREFIX + fileUploadFile.getFileName()));
fileUploadFile.setStarPos(0);
int byteRead;
int lastLength = 0;
RandomAccessFile randomAccessFile;
randomAccessFile = new RandomAccessFile(fileUploadFile.getFile(), "r");
randomAccessFile.seek(fileUploadFile.getStarPos());
lastLength = (int) randomAccessFile.length();
System.out.println("文件长度:" + randomAccessFile.length());
byte[] bytes = new byte[lastLength];
if ((byteRead = randomAccessFile.read(bytes)) != -1) {
fileUploadFile.setEndPos(byteRead);
fileUploadFile.setBytes(bytes);
channel.writeAndFlush(fileUploadFile);
System.out.println("已发送");
} else {
System.out.println("文件已经读完");
}
randomAccessFile.close();
}
public static void main(String[] args) throws Exception {
Channel channel = new Bootstrap()
.group(new NioEventLoopGroup())
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<NioSocketChannel>() {
@Override
protected void initChannel(NioSocketChannel ch) throws Exception {
ch.pipeline().addLast(new StringDecoder());
ch.pipeline().addLast(new StringEncoder());
ch.pipeline().addLast(new ClientHandler());
}
})
.connect(HOST, MESSAGE_PORT)
.sync()
.channel();
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.print("输入消息");
String userInput = scanner.nextLine();
if ("exit".equalsIgnoreCase(userInput)) {
break;
} else {
channel.writeAndFlush(userInput);
}
}
}
public void testFile() throws Exception {
Channel channel = new Bootstrap()
.group(new NioEventLoopGroup())
.channel(NioSocketChannel.class)
.handler(new ChannelInitializer<NioSocketChannel>() {
@Override
protected void initChannel(NioSocketChannel ch) throws Exception {
ch.pipeline().addLast(new ObjectDecoder(Integer.MAX_VALUE, ClassResolvers.weakCachingConcurrentResolver(null)));
ch.pipeline().addLast(new ObjectEncoder());
ch.pipeline().addLast(new ClientHandlerFile());
}
})
.connect(HOST, FILE_PORT)
.sync()
.channel();
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.print("输入file来发送文件");
String userInput = scanner.nextLine();
if ("exit".equalsIgnoreCase(userInput)) {
break;
} else if ("file".equalsIgnoreCase(userInput)) {
File file = new File("C:\\Users\\p30019551244\\Desktop\\demo.txt");
FileUploadFile fileUploadFile = new FileUploadFile();
fileUploadFile.setFile(file);
fileUploadFile.setFileName("1234567.txt");
fileUploadFile.setStarPos(0);
int byteRead;
int start = 0;
int lastLength = 0;
RandomAccessFile randomAccessFile;
try {
randomAccessFile = new RandomAccessFile(fileUploadFile.getFile(), "r");
randomAccessFile.seek(fileUploadFile.getStarPos());
lastLength = (int) randomAccessFile.length() ;
System.out.println("文件长度:" + randomAccessFile.length());
byte[] bytes = new byte[lastLength];
if ((byteRead = randomAccessFile.read(bytes)) != -1) {
fileUploadFile.setEndPos(byteRead);
fileUploadFile.setBytes(bytes);
channel.writeAndFlush(fileUploadFile);
System.out.println("已发送");
} else {
System.out.println("文件已经读完");
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException i) {
i.printStackTrace();
}
} else {
System.out.println("发送信息");
channel.writeAndFlush(userInput);
}
}
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!