java实现PC之间的udp数据单向传输

时间:2021-10-20 23:07:29

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

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

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

UDPClient端源代码:

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端源代码:

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);
}
}

  

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

java实现PC之间的udp数据单向传输的更多相关文章

  1. java实现数据库之间批量插入数据

    package comnf147Package; import java.sql.*; public class DateMigrationLagou { //连接SQLite private Con ...

  2. java与javascript之间json格式数据互转

    javascript中对象与字符串的互转 对象转为字符串:通过JSON.encode方法,这个是json.js里面的方法,引入到当前文件就可以了. 字符串转换为对象:①使用JSON.decode方法, ...

  3. java并发编程JUC第十一篇:如何在线程之间进行对等数据交换

    java.util.concurrent.Exchanger可以用来进行数据交换,或者被称为"数据交换器".两个线程可以使用Exchanger交换数据,下图用来说明Exchange ...

  4. Java内存管理:Java内存区域 JVM运行时数据区

    转自:https://blog.csdn.net/tjiyu/article/details/53915869 下面我们详细了解Java内存区域:先说明JVM规范定义的JVM运行时分配的数据区有哪些, ...

  5. Java内存区域(运行时数据区域)和内存模型(JMM)

    Java 内存区域和内存模型是不一样的东西,内存区域是指 Jvm 运行时将数据分区域存储,强调对内存空间的划分. 而内存模型(Java Memory Model,简称 JMM )是定义了线程和主内存之 ...

  6. java:网络编程(UDP (DatagramSocket和DatagramPacket)正则表达式)

    java:网络编程(UDP (DatagramSocket和DatagramPacket)正则表达式) * TCP* 特点:面向连接,点对点的通信,效率较低,但安全可靠* UDP:用户数据报协议,类似 ...

  7. 浅谈UDP&lpar;数据包长度,收包能力,丢包及进程结构选择&rpar;

    UDP数据包长度 UDP数据包的理论长度 udp数据包的理论长度是多少,合适的udp数据包应该是多少呢?从TCP-IP详解卷一第11章的udp数据包的包头可以看出,udp的最大包长度是2^16-1的个 ...

  8. DatagramSocket收发UDP数据包

    Java的Socket通信分为TCP和UDP两种,Socket和ServerSocket类用于TCP通信,DatagramSocket用于UDP通信. 使用DatagramSocket发送UDP数据包 ...

  9. Socket网络通讯开发总结之:Java 与 C进行Socket通讯 &plus; &lbrack;备忘&rsqb; Java和C之间的通讯

    Socket网络通讯开发总结之:Java 与 C进行Socket通讯 http://blog.sina.com.cn/s/blog_55934df80100i55l.html (2010-04-08 ...

随机推荐

  1. 《&period;Net 的冰与火之歌》寄雁传书,你必须知道的C&num;参数知识大盘点

    引言 参数,也叫参变量,是一个变量.在方法签名中随处可见,实现了不同方法间对于数据的寄雁传书,基本上充斥在代码的各个角落里.在方法签名或者原型中,方法名称后的括号包含方法的参数及其类型的完整列表.参数 ...

  2. PHP 底层的运行机制与原理

    PHP说简单,但是要精通也不是一件简单的事.我们除了会使用之外,还得知道它底层的工作原理. PHP是一种适用于web开发的动态语言.具体点说,就是一个用C语言实现包含大量组件的软件框架.更狭义点看,可 ...

  3. eclipse 相同变量高亮显示

    windows-> preferences-> java-> Editor-> Mark Occurences

  4. linux永久更改eth0的ip地址后仍然ping不通过

    编辑文件/etc/sysconfig/network-scripts/ifcfg-eth0 引用:DEVICE=eth0 //设备名称,不要修改 BOOTPROTO=static //不要修改 BRO ...

  5. Android 一个app启动另一个app

    最近,一个app启动另一个app,这个玩法挺火的嘛,有没有试过更新QQ到5.1版本,QQ的健康里面就可以添加其他app,实现从QQ跳转到其他app应用.这个挺好玩的,一下子带来了多少流量啊. 一.先来 ...

  6. C&num; OpenFileDialog

    OpenFileDialog 用于浏览并打开文件,在Windows Forms中使用,表现为标准的Windows对话框. 实例: 1.新建Windows Form Application 2.添加Op ...

  7. Ajax请求传递参数遇到的问题

    想写个同类型的,代码未测. 什么是WebAPI?我的理解是WebAPI+JQuery(前端)基本上能完成Web MVC的功能,即:这么理解吧,WebAPI相当于Web MVC的后台部分. 接下来直接上 ...

  8. Android SDK与API版本的对应关系

    看教程.开发Android程序等很多地方,需要设置Android SDK的版本,而其要我们写的却是API版本的数字, 为了方便查看 Android SDK与API版本的对应关系 我在SDK Manag ...

  9. 键值编码KVC

    动态设置:setValue:属性值 forKey:属性名用于简单路径:setValue:属性值 forKeyPath:属性路径用于复合路径,例如Person有一个Account类型的属性,那么pers ...

  10. install python in wine

    wget http://www.kegel.com/wine/winetricks chmod +x winetricks ./winetricks 钩选msxml3就可以了. ___________ ...