本示例包括两个客户端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. Python之路PythonNet,第三篇,网络3

    pythonnet   网络3 udp 通信 recvfrom sendtofork 多进程并发threading 多线程并发socketserver 系统模块 套接字的属性 setsockopt g ...

  2. [LeetCode&Python] Problem 404. Sum of Left Leaves

    Find the sum of all left leaves in a given binary tree. Example: 3 / \ 9 20 / \ 15 7 There are two l ...

  3. [Data Structure] Stack Implementation in Python

    We can realize a Stack as an adaptation of a Python List. S.push(e)=L.append(e) S.pop()=L.pop() S.to ...

  4. generator插件配置方式使用

    generator插件配置方式使用 <build> <plugins> <plugin> <groupId>org.mybatis.generator& ...

  5. Eclipse实现数据库反向生成实体类(pojo)-------(插件安装和实现步骤的说明)

    一.插件安装 1.下载插件: http://jaist.dl.sourceforge.net/sourceforge/jboss/HibernateTools-3.2.4.Beta1-R2008103 ...

  6. 【liunx】时间处理函数

    一.脚本示例 [mylinuxaccount@linux01 ~]$ date +%Y%m%d 20171224 [mylinuxaccount@linux01 ~]$ date +%F 2017-1 ...

  7. node学习笔记之io.sockets

    socket.get和socket.set函数已经失效,代码修改如下所示: 服务器端: var httpd = require('http').createServer(handler); var i ...

  8. 用setuptools_scm来自动控制Python包的版本

    手动管理Python包的版本号一段时间后,寻求自动化的手段,是自然而然的. 手动管理版本 手动管理Python包的版本,需要注意两个方面: 每次发布新包前,要更新包的版本号. 在安装后的默认模块下应该 ...

  9. torchvision库简介(翻译)

    部分跟新于:4.24日    torchvision 0.2.2.post3 torchvision是独立于pytorch的关于图像操作的一些方便工具库. torchvision的详细介绍在:http ...

  10. oracle重做日志文件硬盘坏掉解决方法

    rman target/ list backup; list backup summary; 删除数据库数据文件夹下的log日志,例如/u01/app/oracle/oradata/ORCL下的所有后 ...