搭错车的小火柴

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  80 随笔 :: 0 文章 :: 40 评论 :: 19万 阅读
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

本示例包括两个客户端UDPClient和MyServer。UDPClient发送数据到MyServer,MyServer负责接收数据。可传输文本、视频、音频、图片等。

最近我在学习这一块,写个例子。

(注:如果要在不同PC间运行,请修改UDPclient中的环回地址为测试server的真实ip地址,并关闭双方的windows defender。2017-04-10)

UDPClient端源代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GridLayout;
import java.io.File;
import java.io.FileInputStream;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.UnknownHostException;
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.border.EmptyBorder;
import javax.swing.SwingConstants;
 
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
 
 
public class UDPClient extends JFrame {
 
private JPanel pane = new JPanel();//防止jbutton的面板
private JButton button_send=new JButton ("选择并发送文件");
private JLabel label_client_ip = new JLabel("本机ip:",JLabel.CENTER);
private JLabel label_server_ip = new JLabel("目标ip:",JLabel.CENTER);
private JLabel label_client_port = new JLabel("本机端口:6000",JLabel.CENTER);
private JLabel label_server_port = new JLabel("目标端口:10000",JLabel.CENTER);
private JLabel label_file_state = new JLabel("文件当前状态:无任务",JLabel.CENTER);
 
private InetAddress client_ip = null;//本机ip
private InetAddress server_ip = null;//目标ip
private int client_port;//本机port
private int server_port;//目标port最小值
 
DatagramSocket socket_ack;//监听服务器端返回ack or nak
 
String filename = null;
File file ;//传送的文件
 
/**
* Create the frame.
* @param client_name : the title of this application
* @param server_ip : destination ip
* @param client_port : my port
* @param server_port : destination port
*/
public UDPClient(String client_name ,String ip,int myport,int otherport ) {
super (client_name);//程序标题栏
 
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置关闭窗口操作
setBounds(100, 100, 400, 500);//设置窗口大小
getContentPane().setLayout(new GridLayout (6,1,7,7));
//设置全局字体
Font font = new Font("楷体",Font.PLAIN,20);
label_client_ip.setFont(font);
label_server_ip.setFont(font);
label_client_port.setFont(font);
label_server_port.setFont(font);
label_file_state.setFont(font);
button_send.setBackground(Color.LIGHT_GRAY);
button_send.setFont(font); 
//在面板上放置组件
getContentPane().add(label_client_ip);
getContentPane().add(label_server_ip);
getContentPane().add(label_client_port);
getContentPane().add(label_server_port);
getContentPane().add(pane);
pane.add(button_send);
getContentPane().add(label_file_state);
this.setVisible(true);
 
this.server_port=otherport;//获得目标端口
this.client_port=myport;//获得发送端口
 
/*
* 给button_send增加监听事件addActionListener
*/
 
button_send.addActionListener(new ActionListener(){
 
@Override
public void actionPerformed(ActionEvent e) {
// 选择要发送的文件
JFileChooser filechooser = new JFileChooser();
int result = filechooser.showOpenDialog(UDPClient.this);
if (result == JFileChooser.APPROVE_OPTION) {
try{
File file1 = filechooser.getSelectedFile();//选择的文件
file=file1;
try{
//将文件名发送过去
String filename1 = file1.getName();// 文件名
String tip = "有文件,请接收:" + filename1;
byte[] fileNameBuf = tip.getBytes();// 字节buf
DatagramSocket socket = new DatagramSocket();
DatagramPacket packet = new DatagramPacket(//封装packet
fileNameBuf, fileNameBuf.length,
UDPClient.this.server_ip, UDPClient.this.server_port);
socket.send(packet);//发送
System.out.println(new String(packet.getData()));
//socket.close();
UDPClient.this.label_file_state.setText("文件当前状态:文件正在传输...");
//将文件写入内存
FileInputStream fis=new FileInputStream(file);
//发送文件长度
int filelen=fis.available();
String filelenStr=""+filelen;
byte[] filelenBuf=filelenStr.getBytes();
//DatagramSocket socket = new DatagramSocket();
packet = new DatagramPacket(filelenBuf,filelenBuf.length,server_ip,UDPClient.this.server_port+1);
socket.send(packet);
System.out.println(new String(packet.getData()));
//socket.close();
 
//发送文件主体
byte[] buffer = new byte[1024];
int blocknum=filelen/buffer.length;//将文件分成1024个字节的block,blocknum是块的个数,即循环次数
int lastsize=filelen%buffer.length;//最后一个packet的字节数
 
//socket=new DatagramSocket();
for (int i=0;i<blocknum;i++){
fis.read(buffer, 0, buffer.length);//从文件流读入buf中
packet=new DatagramPacket(buffer,buffer.length,server_ip,UDPClient.this.server_port+2);
socket.send(packet);
System.out.println(new String(packet.getData()));
Thread.sleep(1);//简单的防止丢包
}
//发送最后一个block的内容
fis.read(buffer, 0, lastsize);
packet=new DatagramPacket(buffer,buffer.length,server_ip,UDPClient.this.server_port+2);
socket.send(packet);
System.out.println(new String(packet.getData()));
Thread.sleep(1);
//关闭fis和socket
fis.close();
socket.close();
 
UDPClient.this.label_file_state.setText("文件当前状态:文件传输完毕。");
UDPClient.this.label_file_state.setText("文件当前状态::无任务");
} catch (Exception e1){
System.out.println(e1);
}
} catch (Exception ex){
JOptionPane.showMessageDialog(UDPClient.this,
"打开文档出错!");
}
}
}
 
});
 
try{   
//获得本机ip , 目标ip
this.client_ip=InetAddress.getLocalHost();
this.server_ip=InetAddress.getByName(ip);
label_client_ip.setText("本机ip:"+this.client_ip.getHostAddress());//显示在面板上
label_server_ip.setText("目标ip:"+this.server_ip.getHostAddress());//显示在面板上
System.out.println(this.server_ip.getHostAddress());
 
} catch (Exception ex){
System.out.println(ex);
}
}
 
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
UDPClient client = new UDPClient("UDPClient","127.0.0.1",6000,10000);
client.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}

  

MyServer端源代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
import java.awt.Color;
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;
 
import java.awt.*;
 
import javax.swing.*;
 
import java.awt.event.*;
 
public class MyServer extends JFrame {
// 添加属性
private JPanel panel = new JPanel();
private JButton button_receive = new JButton("另存为");
private JLabel label_fileState = new JLabel("当前状态:无任务", JLabel.CENTER);
private JLabel label_cip=new JLabel("本 机ip:",JLabel.CENTER);
private JLabel label_sip=new JLabel("服务器ip:",JLabel.CENTER);
private JLabel label_cport = new JLabel("本机端口:10000",JLabel.CENTER);
private JLabel label_sport = new JLabel("目标端口:6000",JLabel.CENTER);
 
private InetAddress cip = null;//本机ip
private InetAddress sip = null;//对方ip
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 MyServer(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, 400, 500);
// 添加功能代码
this.setLayout(new GridLayout(6, 1, 7, 7));
button_receive.setFont(new Font("楷体", 1, 20));
button_receive.setBackground(Color.LIGHT_GRAY);
Font font = new Font("楷体",Font.PLAIN,20);
label_cip.setFont(font);
label_sip.setFont(font);
label_cport.setFont(font);
label_sport.setFont(font);
label_fileState.setFont(font);
//this.add(panel);
this.add(label_cip);
this.add(label_sip);
this.add(label_cport);
this.add(label_sport); 
this.add(button_receive);
this.add(label_fileState);
 
this.setVisible(true);
//
this.otherport = otherport;
this.myport = myport;
//
button_receive.addActionListener(new ActionListener() {// 吧file1另存为file2
public void actionPerformed(ActionEvent e) {
// 选择要接收的文件
JFileChooser filechooser = new JFileChooser();
int result = filechooser.showSaveDialog(MyServer.this);
if (result == JFileChooser.APPROVE_OPTION) {
try {
File file2 = filechooser.getSelectedFile();
System.out.println("选择文件\n");
try {
File file1 = new File("D:\\TT\\" + filename);
System.out.println(filename+"选择文件\n");
saveAs(file1, file2);
System.out.println("sava文件\n");
} catch (Exception ex) {
System.out.println(ex);
}
} catch (Exception ex) {
JOptionPane.showMessageDialog(MyServer.this,
"打开保存出错!");
}
}
}
});
 
try{
this.cip=InetAddress.getLocalHost();
this.sip = InetAddress.getByName(str_ip);
label_cip.setText("本机ip:"+this.cip.getHostAddress());//显示在面板上
label_sip.setText("目标ip:"+this.sip.getHostAddress());//显示在面板上
System.out.println(this.sip.getHostAddress()); 
 
socket = new DatagramSocket(this.myport);
socket1 = new DatagramSocket(this.myport + 1);
socket2 = new DatagramSocket(this.myport + 2);
 
System.out.println("等待接受文件...");
while(true){
//接收文件名称
byte filetipBuf[] = new byte[256];// 防止文件名字过长(此处最长256个字符)
DatagramPacket packet_tip = new DatagramPacket(filetipBuf,
0, filetipBuf.length);
socket.receive(packet_tip);
System.out.println(new String(packet_tip.getData()));
String str_filetip = new String(packet_tip.getData(),
0,packet_tip.getLength());
filename = str_filetip.substring(8);   
 
//接收文件长度(字节数)
byte[] fileLenBuf = new byte[12];// 可以传输1T的文件
DatagramPacket packet_len = new DatagramPacket(fileLenBuf,fileLenBuf.length);
socket1.receive(packet_len);
System.out.println(new String(packet_len.getData()));
String str_fileLen = new String(fileLenBuf,
0,packet_len.getLength());
fileLen = Integer.parseInt(str_fileLen);
label_fileState.setText("当前状态:正在接收!");
 
//接收文件内容
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);
socket2.receive(packet_file);// 通过套接字接收数据
System.out.println(new String(packet_file.getData()));
fos.write(buffer, 0, 1024);// 写入文件
}
// 接收最后一点点零头
packet_file = new DatagramPacket(buffer, 0, lastSize);
socket2.receive(packet_file);// 通过套接字接收数据
System.out.println(new String(packet_file.getData()));
fos.write(buffer, 0, lastSize);// 写入文件
fos.close();
// 反馈包
label_fileState.setText("文件接收完毕!");
label_fileState.setText("当前状态:无任务");
//  socket.close();
//  socket1.close();
//  socket2.close();
}
}catch (Exception ex)
{
System.out.println("1");
}  
}
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);
}
}
 
///////////////////////////////////////////////
public static void main(String args[]) {
new MyServer("Server", "127.0.0.1", 6000, 10000);
}
}

  

 

本机环回地址测试通过,如有问题,请指正。

posted on   搭错车的小火柴  阅读(2154)  评论(2编辑  收藏  举报
编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示