Compare commits
5 Commits
Author | SHA1 | Date |
---|---|---|
|
7d2bd6175b | |
|
9567c1defe | |
|
34699ff89d | |
|
52a99a220a | |
|
f1eb943f08 |
|
@ -15,7 +15,7 @@
|
|||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.java.version>21</project.java.version>
|
||||
<project.java.version>1.8</project.java.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
|
|
@ -7,6 +7,7 @@ import com.xiaoliu.handler.FileSendClientHandler;
|
|||
import com.xiaoliu.handler.LoginResponseHandler;
|
||||
import com.xiaoliu.protocol.FilePacket;
|
||||
import com.xiaoliu.protocol.request.LoginPacket;
|
||||
import com.xiaoliu.window.MainWindow;
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.channel.*;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
|
@ -73,9 +74,10 @@ public class Client {
|
|||
log.info("连接服务器成功");
|
||||
Channel channel = future.channel();
|
||||
joinCluster(channel);
|
||||
|
||||
MainWindow.setStatus(0);
|
||||
} else {
|
||||
log.info("连接服务器失败");
|
||||
MainWindow.setStatus(1);
|
||||
}
|
||||
|
||||
future.channel().closeFuture().sync();
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
package com.xiaoliu;
|
||||
|
||||
import com.formdev.flatlaf.FlatDarculaLaf;
|
||||
import com.formdev.flatlaf.themes.FlatMacLightLaf;
|
||||
import com.xiaoliu.window.MainWindow;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
|
@ -12,8 +12,9 @@ public class Main {
|
|||
public static void main(String[] args ){
|
||||
log.info("服务启动中...");
|
||||
try {
|
||||
UIManager.setLookAndFeel(new FlatDarculaLaf());
|
||||
} catch (UnsupportedLookAndFeelException e) {
|
||||
UIManager.setLookAndFeel(new FlatMacLightLaf());
|
||||
//UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
||||
} catch (Exception e) {
|
||||
log.error("UnsupportedLookAndFeelException: {}", e.getMessage());
|
||||
}
|
||||
SwingUtilities.invokeLater(() -> new MainWindow().setVisible(true));
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.xiaoliu.handler;
|
|||
import com.xiaoliu.codec.Codec;
|
||||
import com.xiaoliu.protocol.FilePacket;
|
||||
import com.xiaoliu.protocol.Packet;
|
||||
import com.xiaoliu.window.MainWindow;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
|
@ -43,6 +44,7 @@ public class FileSendClientHandler extends ChannelInboundHandlerAdapter {
|
|||
ctx.writeAndFlush(fileRegion).addListener(future -> {
|
||||
if (future.isSuccess()) {
|
||||
log.info("{} 发送完成...", file.getName());
|
||||
MainWindow.notify("文件发送完成:" + file.getName());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -35,6 +35,9 @@ public class MainWindow extends JFrame {
|
|||
|
||||
// 初始化UI组件
|
||||
initializeComponents();
|
||||
|
||||
//tuichu
|
||||
hock();
|
||||
}
|
||||
|
||||
private void initStatusLabel() {
|
||||
|
@ -43,14 +46,29 @@ public class MainWindow extends JFrame {
|
|||
statusLabel.setText("未连接");
|
||||
}
|
||||
|
||||
public void setStatusLabel(String text, Color color ){
|
||||
if(statusLabel == null){
|
||||
public void setStatusLabel(String text, Color color) {
|
||||
if (statusLabel == null) {
|
||||
initStatusLabel();
|
||||
}
|
||||
statusLabel.setText(text);
|
||||
statusLabel.setForeground(color);
|
||||
}
|
||||
|
||||
public static void setStatus(int status) {
|
||||
if (statusLabel == null) {
|
||||
return;
|
||||
}
|
||||
if (status == 0) {
|
||||
statusLabel.setText("已连接");
|
||||
statusLabel.setForeground(Color.GREEN);
|
||||
notify("已连接服务器 ...");
|
||||
} else {
|
||||
statusLabel.setText("未连接");
|
||||
statusLabel.setForeground(Color.RED);
|
||||
notify("连接失败 ...");
|
||||
}
|
||||
}
|
||||
|
||||
private void initializeComponents() {
|
||||
// 在这里添加你的组件初始化代码
|
||||
// 创建一个JTextArea用于显示日志
|
||||
|
@ -63,41 +81,40 @@ public class MainWindow extends JFrame {
|
|||
|
||||
// 将JScrollPane添加到窗口中
|
||||
getContentPane().add(scrollPane, BorderLayout.CENTER);
|
||||
JLabel adress = new JLabel();
|
||||
adress.setText("地址:");
|
||||
JLabel address = new JLabel();
|
||||
address.setText("地址:");
|
||||
JTextField textField = new JTextField(20); // 参数20指定了文本框的列数
|
||||
JButton sendButton = new JButton("连接");
|
||||
JButton stopButton = new JButton("断开");
|
||||
stopButton.setEnabled(false);
|
||||
sendButton.addActionListener(e ->{
|
||||
sendButton.addActionListener(e -> {
|
||||
String text = textField.getText();
|
||||
String[] split = text.split(":");
|
||||
if(split.length < 2){
|
||||
if (split.length < 2) {
|
||||
JOptionPane.showMessageDialog(this, "请输入正确地址", "输入错误", JOptionPane.ERROR_MESSAGE);
|
||||
return;
|
||||
}
|
||||
String host = split[0];
|
||||
String port = split[1];
|
||||
setLogText("连接到: "+ host + ":" + port);
|
||||
setLogText("连接到: " + host + ":" + port);
|
||||
new Thread(() -> {
|
||||
//新起一个县城去初始化netty
|
||||
try {
|
||||
sendButton.setEnabled(false);
|
||||
setLogText("连接成功...");
|
||||
setStatusLabel("已连接", Color.GREEN);
|
||||
stopButton.setEnabled(true);
|
||||
Client.init(host, Integer.parseInt(port));
|
||||
} catch (Exception ex) {
|
||||
setLogText("连接失败...");
|
||||
sendButton.setEnabled(true);
|
||||
stopButton.setEnabled(false);
|
||||
setStatusLabel("已连接", Color.RED);
|
||||
setStatusLabel("未连接", Color.RED);
|
||||
JOptionPane.showMessageDialog(this, "连接失败,请检查...", "连接", JOptionPane.ERROR_MESSAGE);
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}).start();
|
||||
});
|
||||
|
||||
JPanel northPanel = new JPanel();
|
||||
northPanel.add(adress);
|
||||
northPanel.add(address);
|
||||
northPanel.add(textField);
|
||||
northPanel.add(sendButton);
|
||||
northPanel.add(statusLabel, BorderLayout.WEST);
|
||||
|
@ -109,7 +126,6 @@ public class MainWindow extends JFrame {
|
|||
// 示例:添加一个按钮,点击时向文本区域添加日志信息
|
||||
JButton startButton = new JButton("发送");
|
||||
|
||||
|
||||
startButton.addActionListener(e -> {
|
||||
JFileChooser fileChooser = new JFileChooser();
|
||||
fileChooser.setCurrentDirectory(new java.io.File(System.getProperty("user.home") + "/Desktop"));
|
||||
|
@ -126,7 +142,7 @@ public class MainWindow extends JFrame {
|
|||
log.info("文件大小:{}", file.length());
|
||||
new Thread(() -> {
|
||||
//开一个新县城去泡发送程序
|
||||
setLogText("文件发送开始: "+selectedFilePath);
|
||||
setLogText("文件发送开始: " + selectedFilePath);
|
||||
Client.send(file);
|
||||
}).start();
|
||||
|
||||
|
@ -138,6 +154,7 @@ public class MainWindow extends JFrame {
|
|||
Client.shutdown();
|
||||
setStatusLabel("未连接", Color.RED);
|
||||
sendButton.setEnabled(true);
|
||||
stopButton.setEnabled(false);
|
||||
});
|
||||
|
||||
|
||||
|
@ -157,18 +174,25 @@ public class MainWindow extends JFrame {
|
|||
SwingUtilities.invokeLater(() -> new MainWindow().setVisible(true));
|
||||
}
|
||||
|
||||
public JTextArea getLogTextArea(){
|
||||
if(logTextArea == null){
|
||||
public JTextArea getLogTextArea() {
|
||||
if (logTextArea == null) {
|
||||
initLogTextArea();
|
||||
}
|
||||
return logTextArea;
|
||||
}
|
||||
|
||||
public void setLogText(String text){
|
||||
public static void notify(String text) {
|
||||
if (logTextArea == null) {
|
||||
return;
|
||||
}
|
||||
logTextArea.append(text + "\n");
|
||||
}
|
||||
|
||||
public void initLogTextArea(){
|
||||
public void setLogText(String text) {
|
||||
logTextArea.append(text + "\n");
|
||||
}
|
||||
|
||||
public void initLogTextArea() {
|
||||
// 在这里添加你的组件初始化代码
|
||||
// 创建一个JTextArea用于显示日志
|
||||
logTextArea = new JTextArea();
|
||||
|
@ -182,4 +206,9 @@ public class MainWindow extends JFrame {
|
|||
getContentPane().add(scrollPane, BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
public void hock() {
|
||||
log.info("退出执行...");
|
||||
//优雅退出
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(Client::shutdown));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.java.version>21</project.java.version>
|
||||
<project.java.version>1.8</project.java.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
|
|
@ -10,6 +10,8 @@ public class FilePacket extends Packet {
|
|||
|
||||
File file;
|
||||
|
||||
long fileLength;
|
||||
|
||||
int ACK;
|
||||
|
||||
@Override
|
||||
|
@ -22,10 +24,12 @@ public class FilePacket extends Packet {
|
|||
|
||||
public FilePacket(File file) {
|
||||
this.file = file;
|
||||
this.fileLength = file.length();
|
||||
}
|
||||
|
||||
public FilePacket(File file, int ACK) {
|
||||
this.file = file;
|
||||
this.fileLength = file.length();
|
||||
this.ACK = ACK;
|
||||
}
|
||||
|
||||
|
@ -44,4 +48,12 @@ public class FilePacket extends Packet {
|
|||
public void setACK(int ACK) {
|
||||
this.ACK = ACK;
|
||||
}
|
||||
|
||||
public long getFileLength() {
|
||||
return fileLength;
|
||||
}
|
||||
|
||||
public void setFileLength(long fileLength) {
|
||||
this.fileLength = fileLength;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,14 @@ public class LoginPacket extends Packet {
|
|||
|
||||
boolean exec = false;
|
||||
|
||||
public void flush() {
|
||||
this.exec = false;
|
||||
this.fileName = null;
|
||||
this.fileLength = 0;
|
||||
this.readLength = 0;
|
||||
this.fileOutputStream = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Byte getCommand() {
|
||||
return LOGIN_PACKET_REQUEST;
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.java.version>21</project.java.version>
|
||||
<project.java.version>1.8</project.java.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
@ -27,7 +27,7 @@
|
|||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>sane-service-v${project.version}</finalName>
|
||||
<finalName>NettyService-v${project.version}</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
|
|
|
@ -25,8 +25,8 @@ public class FilePacketServerHandler extends SimpleChannelInboundHandler<FilePac
|
|||
}
|
||||
loginPacket.setExec(true);
|
||||
loginPacket.setFileName(file.getName());
|
||||
loginPacket.setFileLength(file.length());
|
||||
loginPacket.setFileOutputStream(new FileOutputStream(new File("./server-receive-" + file.getName())));
|
||||
loginPacket.setFileLength(packet.getFileLength());
|
||||
loginPacket.setFileOutputStream(new FileOutputStream(new File("./service-receive-" + file.getName())));
|
||||
// FileReceiveServerHandler.fileLength = file.length();
|
||||
// FileReceiveServerHandler.outputStream = new FileOutputStream(
|
||||
// new File("./server-receive-" + file.getName())
|
||||
|
|
|
@ -27,7 +27,7 @@ public class FileReceiveServerHandler extends ChannelInboundHandlerAdapter {
|
|||
ByteBuf byteBuf = (ByteBuf) msg;
|
||||
int type = byteBuf.getInt(0);
|
||||
if (type != Codec.TYPE) {
|
||||
loginPacket.setReadLength(loginPacket.getReadLength()+byteBuf.readableBytes());
|
||||
loginPacket.setReadLength(loginPacket.getReadLength() + byteBuf.readableBytes());
|
||||
//readLength += byteBuf.readableBytes();
|
||||
writeToFile(byteBuf, loginPacket.getFileOutputStream());
|
||||
sendComplete(loginPacket);
|
||||
|
@ -43,19 +43,22 @@ public class FileReceiveServerHandler extends ChannelInboundHandlerAdapter {
|
|||
byteBuf.release();
|
||||
}
|
||||
|
||||
private void sendComplete(long readLength) throws IOException {
|
||||
if (readLength >= fileLength) {
|
||||
log.info("文件接收完成.....");
|
||||
outputStream.close();
|
||||
}
|
||||
}
|
||||
// private void sendComplete(long readLength) throws IOException {
|
||||
// if (readLength >= fileLength) {
|
||||
// log.info("文件接收完成.....");
|
||||
// outputStream.close();
|
||||
// }
|
||||
// }
|
||||
|
||||
private void sendComplete(LoginPacket loginPacket) throws IOException {
|
||||
log.debug("ReadLength {}", loginPacket.getReadLength());
|
||||
log.debug("FileLength {}", loginPacket.getFileLength());
|
||||
if (loginPacket.getReadLength() >= loginPacket.getFileLength()) {
|
||||
log.info("文件接收完成...");
|
||||
loginPacket.setExec(false);
|
||||
loginPacket.setReadLength(0);
|
||||
loginPacket.getFileOutputStream().close();
|
||||
if(loginPacket.getFileOutputStream() != null){
|
||||
loginPacket.getFileOutputStream().close();
|
||||
}
|
||||
loginPacket.flush();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue