本示例包括两个客户端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(数据包长度,收包能力,丢包及进程结构选择)

    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通讯 + [备忘] Java和C之间的通讯

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

随机推荐

  1. i.MX6 设备树 GPIO 默认值

    /********************************************************************** * i.MX6 设备树 GPIO 默认值 * 说明: * ...

  2. pycharm中如何安装Scrapy库

    先打开pycharm软件. 然后先安装pywin32和setuptools库. 安装成功后再尝试Twisted库,如果失败,就去晚上下载一个库:https://www.lfd.uci.edu/~goh ...

  3. SVD分解求解旋转矩阵

    1.设是两组Rd空间的点集,可根据这两个点集计算它们之间的旋转平移信息. 2.设R为不变量,对T求导得: 令 则 将(4)带入(1)得: 令 则 (相当于对原来点集做减中心点预处理,再求旋转量) 3. ...

  4. maven 构建 war文件&&Glassfish运行+部署war文件+访问(命令行模式)

    Glassfish常用命令 asadmin  start-domain  --verbose                 #启动Glassfish服务器(默认domain1) ,并在终端显示相关信 ...

  5. markdown使用问题

    1.配置自定义的markdown.css https://github.com/sameer1994kiki/markdown-css 2.代码块 一行`` 多行 ``` <code>&l ...

  6. CCF-棋局评估 201803-04(版本 2.0)------(之前写了一个臃肿的1.0版 ,还沾沾自喜 233)

    核心 : 博弈搜索树     双方得分互为相反数 dfs (x,y,player): 玩家player下完(x,y)之后的得分最大值 易错: 先判断输赢,再判断平局 待改进: check() 函数写的 ...

  7. 20155208 2016-2017-2 《Java程序设计》课程总结

    20155208 2016-2017-2 <Java程序设计>课程总结 一.每周作业及实验报告链接汇总 一路无悔 感恩有你(预备作业一):浅谈师生关系及对java学习的期望. 精益求精,从 ...

  8. HDU 2561

    F - 第二第二 Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit Status Prac ...

  9. test-ipv6

    http://test-ipv6.com/ ! 你的公网 IPv4 地址是 89.42.31.211! 你的公网 IPv6 地址是 2001:ac8:21:8::376e:989b! 你已接入 IPv ...

  10. (5)MySQL的查询:模糊查询(通配符查询like)、限制符查询(limit)、排序查询(order by)、分组查询(group by)、(子查询)

    注意事项 指令语法的优先级: where > group by >order by > limit 例:select count(id) as cnt,age from tablen ...