UDP(用户数据报协议)就像日常生活中的邮件投递,是不能保证可靠地寄到目的地。UDP是无连接的,对系统资源的要求较少,UDP可能丢包,也不保证数据顺序。但是对于网络游戏和在线视频等要求传输快,实时性高,质量可稍差一点的数据传输,UDP还是非常不错的。UDP是无连接协议,不需要像TCP一样监听端口,建立连接,然后才能进行通信。

java.net包中提供了两个类:DatagramSocket和DatagramPacket,用来支持UDP通信。

DatagramSocket用于在程序之间建立传送数据报的通信连接。

DatagramPacket用来表示数据报包,是数据传输的载体。DatagramPacket实现无连接数据包投递服务,每次投递数据包仅限根据该包中信息从一台机器路由到另一台机器。从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按不同的顺序到达,不保证包都能到达目的。

案例一:文件上传工具

服务端UploadServer代码如下:

package udp;import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;public class UploadServer {public static void main(String[] args) {System.out.println("服务器端运行...");//创建一个子线程Thread t=new Thread(()->{try (//创建DatagramSocket对象,指定本地主机端口8080。//【作为服务器一般应明确指定绑定的端口】DatagramSocket socket=new DatagramSocket(8080);FileOutputStream fout=new FileOutputStream("TestDir/subDir/coco.jpg");BufferedOutputStream out=new BufferedOutputStream(fout)){//准备一个缓冲区byte[] buffer=new byte[1024];//循环接收数据包while(true){//创建数据包对象,用来接收数据DatagramPacket packet=new DatagramPacket(buffer, buffer.length);//接收数据包socket.receive(packet);//接收数据长度int len=packet.getLength();if(len==3){//获得结束标志String flag=new String(buffer,0,3);//判断结束标志,如果是bye,则结束接收if(flag.equals("bye")){break;}}//写入数据到文件输出流out.write(buffer,0,len);}System.out.println("接收完成!");} catch (IOException e) {e.printStackTrace();}});//启动线程t.start();}
}

上述代码创建一个子线程,由于客户端上传的数据分为很多数据包,因此需要一个循环接收数据包,另外,调用后receive()方法会导致线程阻塞,因此需要将接收数据的处理放到一个子线程中。

与TCP Socket不同,UDP Socket无法知道哪些数据包已经是最后一个了,因此需要发送方发出一个特殊的数据包,包中包含了一些特殊标志。然后提取并判断这个标志。

客户端UpdateClient代码如下:

package udp;import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;public class UploadClient {public static void main(String[] args) {System.out.println("客户端运行...");try (//创建DatagramSocket对象,由系统分配可以使用的端口DatagramSocket socket=new DatagramSocket();//创建文件输入流FileInputStream fin=new FileInputStream("TestDir/coco.jpg");//由文件输入流创建缓冲输入流BufferedInputStream in=new BufferedInputStream(fin)){//创建远程主机IP地址对象InetAddress address=InetAddress.getByName("localhost");//准备一个缓冲区byte[] buffer=new byte[1024];//首次读取文件int len=in.read(buffer);while(len!=-1){//创建数据报包对象DatagramPacket packet=new DatagramPacket(buffer,len,address,8080);//发送数据包socket.send(packet);//再次读取文件len=in.read(buffer);}//创建数据报对象DatagramPacket packet=new DatagramPacket("bye".getBytes(),3,address,8080);//发送结束标志socket.send(packet);System.out.println("上传成功!");} catch (IOException e) {e.printStackTrace();}}}

上述代码是上传文件客户端,发送数据不会阻塞线程,因此没有使用子线程。客户端DatagramSocket对象经常自己不指定端口,而是由系统分配可以使用的端口。

在文件内容传输结束以后,需要发送一个结束标志,这个结束标志是字符串"bye",服务器端收到这个字符串则结束接收数据包。

案例二:聊天工具

服务器端ChatServer代码如下:

package udp;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;public class ChatServer {public static void main(String[] args) {System.out.println("服务器运行...");Thread t=new Thread(()->{try(//创建DatagramSocket对象,指定端口8080DatagramSocket socket=new DatagramSocket(8080);//InputStreamReader将字节流转换为字符流BufferedReader keyboardIn=new BufferedReader(new InputStreamReader(System.in))) {while(true){/*接收数据报*///准备一个缓冲区byte[] buffer=new byte[128];DatagramPacket packet=new DatagramPacket(buffer,buffer.length);socket.receive(packet);//接收数据长度int len=packet.getLength();String str=new String(buffer,0,len);//打印接收的数据System.out.printf("从客户端接收的数据:【%s】\n",str);/*发送数据*///从客户端传来的数据包中得到客户端地址InetAddress address=packet.getAddress();//从客户端传来的数据包中得到客户端端口号int port=packet.getPort();//读取键盘输入的字符串String keyboardInputString=keyboardIn.readLine();//读取键盘输入的字节数组byte[] b=keyboardInputString.getBytes();//创建DatagramPacket对象,用于向客户端发送数据packet=new DatagramPacket(b,b.length,address,port);//向客户端发送数据socket.send(packet);}} catch (IOException e) {e.printStackTrace();}});//启动线程t.start();}}

上述代码创建一个子线程,因为socket.receive(packet)方法会阻塞主线程。服务器给客户端发送数据包,也需要知道它的IP地址和端口号,服务端根据接收的数据包获得客户端的地址和端口号。

客户端ChatClient代码如下:

package udp;import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;public class ChatClient {public static void main(String[] args) {System.out.println("客户端运行...");//创建一个子线程Thread t=new Thread(()->{try (//创建DatagramSocket对象,由系统分配可以使用的端口DatagramSocket socket=new DatagramSocket();BufferedReader keyboardIn=new BufferedReader(new InputStreamReader(System.in))){while(true){/*发送数据*///准备一个缓冲区byte[] buffer=new byte[128];//服务器IP地址InetAddress address=InetAddress.getByName("localhost");//服务器端口号int port=8080;//读取键盘输入的字符串String keyboardInpuStream=keyboardIn.readLine();//退出循环,结束线程if(keyboardInpuStream.equals("bye")){break;}//读取键盘输入的字节数组byte[] b=keyboardInpuStream.getBytes();//创建DatagramPacket对象DatagramPacket packet=new DatagramPacket(b, b.length,address,port);//发送socket.send(packet);/*接收数据报*/packet=new DatagramPacket(buffer,buffer.length);socket.receive(packet);//接收数据长度int len=packet.getLength();String str=new String(buffer,0,len);//打印接收的数据System.out.printf("从服务器接收的数据:【%s】\n",str);}}catch (IOException e) {e.printStackTrace();}});//启动线程t.start();}
}

客户端可以通过键盘输入"bye",退出循环结束线程。

【Java】UDP Socket编程案例——文件传输聊天工具相关推荐

  1. 【Java】TCP Socket编程案例——文件传输聊天工具

    TCP(传输控制协议)是面向连接的可靠数据传输协议.TCP连接一旦建立起来,一直占用,直到关闭连接.另外,TCP为了保证数据的正确性,会重发一切没有收到的数据,还会对数据内容进行验证,并保证数据传输的 ...

  2. java socket 传多个文件下载,Socket编程多文件传输

    有子曰:"其为人也孝弟,而好犯上者,鲜矣:不好犯上,而好作乱者,未之有也.君子务本,本立而道生.孝弟也者,其为仁之本与!" 项目介绍:基于TCP协议实现多文件传输 将F盘test文 ...

  3. socket编程实现文件传输功能

    这节我们来完成 socket 文件传输程序,这是一个非常实用的例子.要实现的功能为:client 从 server 下载一个文件并保存到本地. 编写这个程序需要注意两个问题: 1) 文件大小不确定,有 ...

  4. socket编程二十二:socket编程实现文件传输功能

    这节我们来完成 socket 文件传输程序,这是一个非常实用的例子.要实现的功能为:client 从 server 下载一个文件并保存到本地. 编写这个程序需要注意两个问题: 1) 文件大小不确定,有 ...

  5. 例程:socket编程实现文件传输功能

    程序要实现的功能:client 从 server 下载一个文件并保存到本地. 编写这个程序需要注意两个问题: (1)文件大小不确定 有可能比缓冲区大很多,调用一次 write()/send() 函数不 ...

  6. socket 编程实现文件传输功能!强无敌,网络通讯的必备知识储备!

    socket 文件传输程序,这是一个非常实用的例子. 要实现的功能为:client 从 server 下载一个文件并保存到本地. 编写这个程序需要注意两个问题: ======== 1) 文件大小不确定 ...

  7. api有哪些 javasocket_基于java的socket编程及API解析

    一.socket通讯过程 1.socket与socket编程简介: socket 被翻译为"套接字",它是计算机之间进行通信的一种约定或一种方式.通过 socket 这种约定,一台 ...

  8. FTP 编程 5 文件传输与目录切换

    FTP 编程 5 文件传输与目录切换     接下来说最后一个 FTP 实现的功能点了,文件传输加上前面几篇文件介绍的功能实现组合起来基本就能实现一个 FTP 程序了,但这个只是简单的实现,和现实中能 ...

  9. python socket编程 实现简单p2p聊天程序

    转载自:https://www.cnblogs.com/wuxie1989/p/7204887.html python socket编程 实现简单p2p聊天程序 目标是写一个python的p2p聊天的 ...

最新文章

  1. 修改Eclipse格式化代默认长度
  2. halcon入门_visionpro和halcon这两款机器视觉软件区别
  3. 【数学建模】聚类分析(评价与决策)
  4. 夸奖对方代码写的好_怎样写好代码(三)
  5. Ubuntu20.04安裝QQ for Linux
  6. Android中的JSON解析方式:json; Gson ; Fastjson
  7. JVM 调优和垃圾回收器说明
  8. oracle活跃用户,监控数据库中的活跃用户及其运行
  9. 第58课 百钱买百鸡 《小学生C++趣味编程》
  10. js怎么获取扫码枪条码_生产扫码计件解决方案
  11. WordPress独立资源下载页面插件 基于美化Xydown插件
  12. 20145235李涛《网络对抗》逆向及Bof基础
  13. 假新闻无处不在:我开源了一个深度学习标记假新闻项目
  14. matlab中 nntwarn off,network的subsindex的定义问题
  15. PAP和CHAP认证
  16. Linux下如何从mysql数据库里导出导入数据
  17. 萤火虫算法matlab实现,萤火虫算法,matlab代码.doc
  18. 关于Android的.so文件你所需要知道的 - 简书
  19. 每个国家对应的语言Locale和国家代码对照表(国际化支持)
  20. 求解答!iframe在IE浏览器加载页面无反应问题

热门文章

  1. 展示魅力东莞,传递亚运激情
  2. 某化工学院安装锐捷elog
  3. oracle 恢复学习 案例1 一个数据文件丢失 完全恢复数据库
  4. 你绝对不知道浏览器还有这样的功能
  5. 快速上手 flask
  6. Linux C 多线程编程----互斥锁与条件变量-转
  7. 分享一个蛋疼的俄罗斯方块小游戏
  8. 蓝桥杯 ALGO-25 算法训练 Car的旅行路线
  9. 计算机编程语言的分类,解释型语言、编译型语言、脚本语言的关系
  10. VBA中msgbox的用法小结