package rgy.com.UDP3;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketAddress;
import java.sql.Date;
import java.text.SimpleDateFormat;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.WindowConstants;
public class Client extends JFrame {
// 添加属性
private JPanel panel = new JPanel();
private JButton button_send = new JButton("文件发送");
private JButton button_receive = new JButton("另存为");
private JTextArea ta = new JTextArea();
private JScrollPane sp = new JScrollPane(ta);
private JTextArea ta_send = new JTextArea();
private JScrollPane sp_send = new JScrollPane(ta_send);
private JLabel label_fileState = new JLabel("文件状态", JLabel.CENTER);
private JLabel label_feedback = new JLabel("反馈", JLabel.CENTER);
//
private InetAddress ip = null;
private int otherport;
private int myport;
DatagramSocket socket;// 接收文件来显提示
DatagramSocket socket1;// 接收文件信息
DatagramSocket socket2;// 接收平时的聊天信息
//
String filename = null;
byte buffer[] = new byte[1024];
int fileLen = 0;
int numofBlock = 0;
int lastSize = 0;
//
String str_name;
//
public Client(String str_name, String str_ip, int otherport, int myport) {
super(str_name);
this.str_name = str_name;
this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
this.setBounds(600, 250, 300, 400);
// 添加功能代码
this.setLayout(new GridLayout(5, 1, 7, 7));
ta.setLineWrap(true);// 换行
this.add(sp);
ta_send.setLineWrap(true);// 换行
this.add(sp_send);
button_send.setFont(new Font("楷体", 1, 20));
button_receive.setFont(new Font("楷体", 1, 20));
panel.add(button_send);
panel.add(button_receive);
this.add(panel);
this.add(label_fileState);
this.add(label_feedback);
//
this.setVisible(true);
//
this.otherport = otherport;
this.myport = myport;
//
button_send.addActionListener(new ActionListener() {// 发送文件
public void actionPerformed(ActionEvent e) {
// 选择要发送的文件
JFileChooser filechooser = new JFileChooser();
int result = filechooser.showOpenDialog(Client.this);
if (result == JFileChooser.APPROVE_OPTION) {
try {
File file = filechooser.getSelectedFile();
try {
// 将文件名发送过去
String str_filename = file.getName();
String str_tip = "有文件,请处理:" + str_filename;
byte[] fileNameBuf = str_tip.getBytes();
DatagramSocket socket = new DatagramSocket();
DatagramPacket packet = new DatagramPacket(
fileNameBuf, fileNameBuf.length,
ip, Client.this.otherport);
socket.send(packet);
socket.close();
//
FileInputStream fis = new FileInputStream(
file);// 从文件中取出写入内存
// 将文件长度发送过去
int fileLen = fis.available();
String str_len = "" + fileLen;
byte[] fileLenBuf = str_len.getBytes();
socket = new DatagramSocket();
packet = new DatagramPacket(fileLenBuf,
fileLenBuf.length, ip,
Client.this.otherport+1);
socket.send(packet);
socket.close();
// 发送文件主体
byte[] buf = new byte[1024];
int numofBlock = fileLen / buf.length;// 循环次数(将该文件分成了多少块)
int lastSize = fileLen % buf.length;// 最后一点点零头的字节数
socket = new DatagramSocket();
for (int i = 0; i < numofBlock; i++) {
fis.read(buf, 0, buf.length);// 写入内存
packet = new DatagramPacket(buf,
buf.length, ip,
Client.this.otherport+1);
socket.send(packet);
Thread.sleep(1); // 简单的防止丢包现象
}
// 发送最后一点点零头
fis.read(buf, 0, lastSize);
packet = new DatagramPacket(buf,
buf.length, ip,
Client.this.otherport+1);
socket.send(packet);
Thread.sleep(1); // 简单的防止丢包现象
//
fis.close();
socket.close();
//
label_fileState.setText("文件传输完毕!");
ta.append("");
//
} catch (Exception ev) {
System.out.println(ev);
}
} catch (Exception ex) {
JOptionPane.showMessageDialog(Client.this,
"打开文档出错!");
}
}
}
});
// /
button_receive.addActionListener(new ActionListener() {// 接收文件
public void actionPerformed(ActionEvent e) {
// 选择要接收的文件
JFileChooser filechooser = new JFileChooser();
int result = filechooser.showSaveDialog(Client.this);
if (result == JFileChooser.APPROVE_OPTION) {
try {
File file2 = filechooser.getSelectedFile();
try {
File file1 = new File("D:\\TT\\" + filename);
saveAs(file1, file2);
//
label_fileState.setText("文件接收完毕!");
ta.append("文件已处理!!\n");
} catch (Exception ex) {
System.out.println(ex);
}
} catch (Exception ex) {
JOptionPane.showMessageDialog(Client.this,
"打开保存出错!");
}
}
}
});
//
ta_send.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent ke) {
String str_chat = Client.this.str_name + " 说: "
+ ta_send.getText();
byte buf[] = str_chat.getBytes();
if (ke.isControlDown() && ke.getKeyCode() == KeyEvent.VK_ENTER) {
try {
DatagramSocket socket = new DatagramSocket();
DatagramPacket packet = new DatagramPacket(buf,
buf.length, ip, Client.this.otherport+2);
socket.send(packet);
ta.append("我说: "+ta_send.getText()+"\n");
ta_send.setText("");
} catch (Exception ex) {
System.out.println(ex);
}
}
}
});
//
try {
ip = InetAddress.getByName(str_ip);
socket = new DatagramSocket(this.myport);
socket1 = new DatagramSocket(this.myport + 1);
socket2 = new DatagramSocket(this.myport + 2);
Timer timer = new Timer();//定时器,刷新接收消息
timer.schedule(new MyTimerTask_receive(),0, 100);
while (socket!=null) {
try {
//
byte filetipBuf[] = new byte[256];// 防止文件名字过长(此处最长256个字符)
DatagramPacket packet_tip = new DatagramPacket(filetipBuf,
0, filetipBuf.length);
socket.receive(packet_tip);
String str_filetip = new String(packet_tip.getData(), 0,
packet_tip.getLength());
filename = str_filetip.substring(8);
ta.append(str_filetip + "\n");
// 接收文件长度(字节数)
byte[] fileLenBuf = new byte[12];// 可以传输1T的文件
DatagramPacket packet_len = new DatagramPacket(fileLenBuf,
fileLenBuf.length);
socket1.receive(packet_len);
String str_fileLen = new String(fileLenBuf, 0,
packet_len.getLength());
fileLen = Integer.parseInt(str_fileLen);
ta.append("文件大小: " + fileLen + "字节, " + (fileLen / 1024)
+ "kb, " + (fileLen / 1024 / 1024) + "Mb\n");
//
DatagramPacket packet_file = new DatagramPacket(buffer, 0,
buffer.length);
numofBlock = fileLen / buffer.length;// 循环次数(将该文件分成了多少块)
lastSize = fileLen % buffer.length;// 最后一点点零头的字节数
File file = new File("D:\\TT\\" + filename);
FileOutputStream fos = new FileOutputStream(file);// 从内存取出存入文件
for (int i = 0; i < numofBlock; i++) {
packet_file = new DatagramPacket(buffer, 0,
buffer.length);
socket1.receive(packet_file);// 通过套接字接收数据
fos.write(buffer, 0, 1024);// 写入文件
}
// 接收最后一点点零头
packet_file = new DatagramPacket(buffer, 0, lastSize);
socket1.receive(packet_file);// 通过套接字接收数据
fos.write(buffer, 0, lastSize);// 写入文件
fos.close();
// 反馈包
} catch (Exception e) {
System.out.println(e);
}
}
} catch (Exception e) {
System.out.println(e);
}
}
public void saveAs(File file1, File file2) {// 把file1另存为file2,并删掉file1
try {
FileInputStream fis = new FileInputStream(file1);
FileOutputStream fos = new FileOutputStream(file2);
byte buf[] = new byte[1024];
int len = 0;
while ((len = fis.read(buf)) != -1) {
fos.write(buf, 0, len);
}
fis.close();
fos.close();
file1.delete();
} catch (Exception ex) {
System.out.println(ex);
}
}
class MyTimerTask_receive extends TimerTask {
public void run() {
try{
byte chatBuf[] = new byte[512];
DatagramPacket packet_chat = new DatagramPacket(chatBuf, 0,
chatBuf.length);
socket2.receive(packet_chat);
String str_chat = new String(packet_chat.getData(), 0,
packet_chat.getLength());
ta.append(str_chat + "\n");
}catch(Exception ex){
System.out.println(ex);
}
}
}
//
public static void main(String args[]) {
new Client("Mary", "127.0.0.2", 6000, 10000);
}
}