JavaEE 网络编程示例1 UDP套接字数据报编程 == 一发一收
鲁吼呀,胶己人!
文章目录
- JavaEE & 网络编程示例1 & UDP套接字数据报编程 ==> 一发一收
- 1. 协议分层(回顾)
- 2. 套接字 Socket
- 2.1 UDP与TCP两组协议的主要区别
- 2.1.1 UDP无连接,TCP有链接
- 2.1.2 UDP不可靠传输,TCP可靠传输
- 2.1.3 UDP面向数据报,TCP面向字节流
- 2.1.4 UDP与TCP 全双工
- 3. 网络编程示例1 ==> 一发一收
- 3.1 DatagramSocket 与 DatagramPacket
- 3.1.1 Socket对象
- 3.1.2 DatagramSocket的一些方法
- 3.1.3 DatagramPacket的一些方法
- 3.2 基于UDP 的 Socket 写一个简单的客户端服务器程序
- 3.2.1 服务器
- 3.2.1.1 读取请求并解析
- 3.2.1.2 计算请求信息为响应信息
- 3.2.1.3 将响应信息打包成【数据报】
- 3.2.1.4 响应数据报信息发送给客户端
- 3.2.1.5 打印日志
- 3.2.1.6 图片分析
- 3.2.2 客户端
- 3.2.2.1 控制台输入请求
- 3.2.2.2 请求信息打包成【数据报】
- 3.2.2.3 通过socket对象将【数据报】发送给服务器
- 3.2.2.4 等待服务器响应
- 3.2.2.5 提取数据报信息并打印日志
- 3.2.2.6 图片分析
- 3.2.3 测试与总结
- 3.3 socket文件怎么存储数据的
JavaEE & 网络编程示例1 & UDP套接字数据报编程 ==> 一发一收
1. 协议分层(回顾)
- 应用层
- 应用程序所在(程序员),数据的用途
- 传输层
- 关注传输过程的起点和终点
- 网络层
- 负责整个传输过程的路径规划
- 数据链路层
- 针对两个相邻节点之间的数据传输
- 物理层
- 硬件设备,基础设施
对于2 和 3 是操作系统内核封装的
对于4 和 5 是硬件和驱动控制的
- 一般程序员只需要关注1 和 2 即可~
- 毕竟 1 要传出去或者接受要经过 2
2. 套接字 Socket
程序员编写网络程序主要编写的是应用层代码
那么,我们就需要第下层协议的提供服务,即 应用层调用传输层提供的API
- socket API,网络编程的重要API
- socket - 插座,不要纠结名词,用就是了~
这些API是C / C++ 风格的,因为操作系统本身就是C / C++ 写的
- JDK针对这些API,封装成Java风格的API
- Java程序员这需要正常使用这些API就足够了~
系统给咱们提供了两组socket API
- 基于UDP的API
- 基于TCP的API
Destination User Prompter
Transmission Control Protocol
2.1 UDP与TCP两组协议的主要区别
- 这两个协议有各自的特点~
- 当然还有其他特点,不做细讲~
2.1.1 UDP无连接,TCP有链接
- 连接:是一种抽象的连接
就比如说谈恋爱和结婚,结婚就是一种有效的抽象连接
- 通信双方都隆重地记录了对方的信息~
如果我们的两台机器在通信的时候,需要单独保存记录两台机器的信息就是有连接,不需要则是无连接
- 注意:不代表无连接就没用到对方的信息,而是只是用到,就仅仅是用到
- 短期恋爱~
小例子:
- DUP无连接
- 发送就完事了,不需要连接
- TCP有连接:
- 先连接才能通信
- 先连接才能通信
2.1.2 UDP不可靠传输,TCP可靠传输
- 可靠传输 不代表百分百能够有效传输,但是会尽力的传输~!
- 传没传成功,是可以心知肚明的
- 不可靠传输 则代表,“无所谓,你收不到不是我的锅“
以上面的那个例子继续说:
- DUP不可靠传输
- 我发了就发了,并不在意对方收没收到
我还记得我高中的时候,老人机发短信给我老爸,叫他来学校载我,结果我不知道我爸没收到,导致我等了2 - 3小时 T.T
- TCP可靠传输
- 不说每次都能通信,但是我一定能知道有没有成功
2.1.3 UDP面向数据报,TCP面向字节流
- 这个跟IO操作的字符流字节流是相似的~
TCP面向字节流:
- 数据传输以字节为基本单位,读写方便灵活
- 不在本章讲解
UDP面向数据报:
- 数据运算是以一个UDP数据报为基本单位(待会儿的重点)
- 读写操作不大灵活
2.1.4 UDP与TCP 全双工
单双工:一条路径,单向通信
- 一边通信完了,另一边才能过去
全双工:一条路径,双向通信
- 这一边朝另一边,另一边朝这一边,是不需要等的
- 除非另一边需要这一边的数据作为前提~
- 这一边朝另一边,另一边朝这一边,是不需要等的
例如马路:
- 对于单双工
- 对于全双工
- 则很有秩序~
- 而两种协议都是全双工的,所以不用操心~
3. 网络编程示例1 ==> 一发一收
- UDP要比TCP简单,先难后易
- 接受新知识的过程可能会很困难,但是这也算是固定写法
- 熟练最重要!!!
- TCP将在后续文章讲到!
- 这是本文章重点!
3.1 DatagramSocket 与 DatagramPacket
- Socket ==> 数据报的Socket对象
- Packet ==> 这个对象就是一个UDP数据报
DUP数据运算的基本单位
3.1.1 Socket对象
在文件操作系统中,在文件操作的 时候提到,不是目录不是普通文件的文件
- 这样特殊的文件有很多,其中就有socket文件
- 而一个Socket对象就对应一个socket文件~
而socket文件并非对应到硬盘的某一个存储区,而是对应到网卡的一个硬件设备
打开命令行(win + R + cmd)输入ipconfig:
- 有线网卡
- 无线网卡:
- 一般网卡都是集成在主板上面的
文件:
- 广义:指代系统资源
- 计算机上的 软件 / 硬件
- 操作系统的基本设计思想: “一切皆文件”【简化逻辑】
- 狭义:指代硬盘上的一块数据存储区域
所以,要相进行网络通信,就需要socket文件对应的这个对象(内存中的变量)去搞事情,从而间接操控网卡
- 输入信息到Socket对象里,就相当于输入信息到socket文件里,就相当于通过网卡发送信息
- 提取Socket对象里的信息,就相当于读取socket文件里的信息,就相当于通过网卡接受信息
3.1.2 DatagramSocket的一些方法
方法名 | 方法说明 |
---|---|
DatagramSocket() | 创建一个Socket,绑定本机任意一个空闲的端口 |
DatagramSocket(int port) | 创建一个Socket,绑定指定的端口(port) |
- 对于不带参数的构造方法,一般用于客户端
- 系统分配一个端口~
- 对于待参数的构造方法,一般用于服务端
小例子:
方法名 | 方法说明 |
---|---|
void receive(DatagramPacket p) | 接受数据报并读取到已有数据报 |
void send(DatagramPacket p) | 发送数据报 |
void close() | 关闭socket文件(避免文件资源泄露,但是很少有关闭的时候,这也符合实际情况) |
- 不纸上谈兵了,等一下实战你就懂了!
3.1.3 DatagramPacket的一些方法
本体:
方法名 | 方法说明 |
---|---|
DatagramPacket(byte[] buf, int length) | 成员buf取参数字节数组的头开始,长度length的部分 |
DatagramPacket(byte[] buf, int offset, int length, SocketAddress address) | 成员buf取参数为字节数组的头开始长度length的部分,并且传入offset(缓冲区偏移量)和socket地址 |
DatagramPacket(byte[] buf, int length, InetAddress address, int port) | 成员buf取参数为字节数组的头开始长度length的部分,并传入包装IP的InetAddress对象,和端口号 |
- 对于不带地址的版本:一般就是接受消息的
- 对于带地址的版本:一般就是用来发送消息的
- 这个地址包括目的地的IP和端口号~
- IP — 确认电脑
- 端口号port — 确定应用程序
- 这个地址包括目的地的IP和端口号~
- 对于第三个构造方法,一般也用于发送信息给服务器的~
- InetAddress是对服务器IP地址的包装
- 端口号代表服务器程序所在的“位置”
方法名 | 方法说明 |
---|---|
InetAddress getAddress() | 获取客户端or服务器的IP地址 |
int getPort() | 获取客户端or服务器的端口号 |
byte[] getData() | 获取数据报里的数据 |
- 不纸上谈兵了,等一下实战你就懂了!
3.2 基于UDP 的 Socket 写一个简单的客户端服务器程序
- 回显服务器(echo server)
- 即,客户端发起的请求,服务器响应一个一模一样的响应
- 请求就是“没有请求”
- 就像这样,老板没给我做,给我回了句一模一样的话
接下来就是书写代码的环节了!
- 第一遍不懂很正常,最终的总结分析可能会对你有很大帮助!
3.2.1 服务器
三个核心工作:
- 读取请求并解析
- 根据请求求得对应响应(回显服务器 无此操作)
- 把响应返回给客户端
构建一个Socket对象
写一个构造方法
- 服务器的固定端口!
- 要处理异常,因为并不是每一次都能绑定成功对应的端口号~
- 此端口号被占用,就会出错!
- 在一个主机里,一个端口在同一时刻只能被一个进程绑定
public UDPEchoServer(int port) throws SocketException {this.socket = new DatagramSocket(port);}
- 启动服务器的主方法
public void start() {System.out.println("启动服务器成功");//服务器一直工作 或者 等待客户端请求//所以说才很少关闭~while(true) {//做那三件事!}
}
3.2.1.1 读取请求并解析
再次重点强调【数据报】是什么
- 数据报是一个对象,而服务器要响应的是里面的【数据String】~
- 数据报为了确定发送对象和确定身份,增加了很多属性和东西~
而我们只需要用socket对象与网卡进行联系,这样就能实现应用层和传输层的数据交换~
而UDP协议,数据传输的基本单位就是【数据报】!
public void start() throws IOException {System.out.println("启动服务器成功");//服务器一直工作 或者 等待客户端请求while(true) {DatagramPacket request = new DatagramPacket(new byte[1024], 1024);//**************** 自带饭盒 ****************socket.receive(request);//request --- 载体//io操作都可能会有IOException异常//盛饭,从网卡里面拿的请求,将其录入已存在的数据报里String request = new String(requestPacket.getData(), 0, requestPacket.getLength());}
}
- Java中的“二进制数据”,可以通过这样构造字符串去解析~
- 解析utf8编码 -------- 三个字节 ==> 一个字符
- 解析二进制数据不要与unicode混了~
- Unicode跟char类型有关~ 两个字节
死循环是因为一个服务器无时无刻都要尝试获取请求~
- 输出型参数:
- 指的是方法并没有返回一个值,而是将值录入到参数里。起到返回的作用
- 不用申请多的空间,也不需要拷贝一份返回并修改原指向
- 例如Set的对象里有一个toArray(T[] ts)方法
- 这个方法也用到了输出型参数
- 再例如字符串转字符数组:
此时,如果还没有客户端发来的数据,咋办?
- receive阻塞等待就行了
- 直到客户端发来请求
- 有点类似于阻塞队列~
3.2.1.2 计算请求信息为响应信息
String response = process(request);
//计算该字符串的响应
public String process(String request) {//回显服务器直接返回原值~return request;
}
3.2.1.3 将响应信息打包成【数据报】
DatagramPacket responsePacket = new DatagramPacket(response.getBytes(),response.getBytes().length,requestPacket.getSocketAddress());
- getSocketAddress ==> 数据报里的客户端主机IP
- 传给客户端得转化为数据报才行
- 而计算数据报的信息计算只能以字符串为对象
3.2.1.4 响应数据报信息发送给客户端
socket.send(responsePacket);
//发送数学报,数据报有客户端的信息,所以可以具体的转发到对方机器
//响应
3.2.1.5 打印日志
System.out.printf("客户端[%s, %d], 发来请求[request]:%s, 其将收到响应[response]:%s\n",requestPacket.getAddress(), requestPacket.getPort(),request, response);
3.2.1.6 图片分析
3.2.2 客户端
三个核心工作:
- 输入台输入请求核心信息,并打包成数据报
- 发送数据报给服务器
- 等待服务器响应
public class UDPEchoClient {private DatagramSocket socket = null;private String serverIP;private int serverPort;}
- 客户端一些必备的属性
- 自己的socket对象,只不过端口号可以随机~
- 服务器的IP和端口 — 决定了发送请求的对象!
//确定服务器
public UDPEchoClient(String serverIP, int serverPort) throws SocketException {this.socket = new DatagramSocket();this.serverIP = serverIP;this.serverPort = serverPort;
}
- 构造方法~
- 传入服务器信息~
- socket对象本身就自动获得该机器的IP
- 经过socket对象的方法,数据报也会染上socket对象的信息也就是发送方的信息~
- 也就是说
- 在服务器视角,收到的请求数据报是有客户端的地址的,而客户端发出需要有服务器的地址
- 在客户端视角,收到的响应数据报是有服务器的地址的,而服务器发出需要有客户端的地址
- socket对象操作默认填入socket对象的信息~
3.2.2.1 控制台输入请求
public void start() throws IOException {//客户端输入信息Scanner scanner = new Scanner(System.in);while(true) {System.out.print("-> ");String request = scanner.nextLine();//next方法以空格或者回车分割!//控制台输入数据报的【主信息】}
}
- 死循环 ==> 客户端无时无刻都可以发送请求
3.2.2.2 请求信息打包成【数据报】
- 现在可没有现成的数据报来获取IP和端口号地址~
这里需要可以利用这个构造方法~
InetAddress对象就是IP的一种包装~
InetAddress.getByName,打包对应的IP地址
这里传入了serverIP,即服务器IP
不用理解太深,用就是了
DatagramPacket requestPacket = new DatagramPacket(request.getBytes(),request.getBytes().length,InetAddress.getByName(serverIP), serverPort);
//打包信息成数据报
//根据ip打包成InetAddress对象
3.2.2.3 通过socket对象将【数据报】发送给服务器
socket.send(requestPacket);
//发送给服务器
3.2.2.4 等待服务器响应
DatagramPacket responsePacket = new DatagramPacket(new byte[1024], 1024);
//等待服务器返回响应
//而两个机器之间是通过数据报传输
socket.receive(responsePacket);
- 做好“饭盒” - 【空数据报】,服务器一旦返回响应,就接下~
同样的,服务器返回前,要阻塞等待~
3.2.2.5 提取数据报信息并打印日志
String response = new String(responsePacket.getData(), 0, responsePacket.getLength());
//获取数据报里面的响应信息!System.out.printf("服务器[%s, %d], 收到请求[request]:%s, 发来响应[response]:%s\n", serverIP,serverPort, request, response);
//打印日志
- 获取【数据报】里的“核心数据”,做成字符串~
3.2.2.6 图片分析
3.2.3 测试与总结
- 在服务器里,有一个main线程:
public static void main(String[] args) throws IOException {UDPEchoServer udpEchoServer = new UDPEchoServer(9090);udpEchoServer.start();
}
- 在客户端也有一个main线程:
public static void main(String[] args) throws IOException {UDPEchoClient udpEchoClient = new UDPEchoClient("10.61.10.239", 9090);udpEchoClient.start();
}
对,没错,这是两个进程!
- 服务器端口号9090是我随便给的!
- 要对应好!
- 服务器IP要自己去找!
win + R + cmd + ipconfig
运行测试:
总结图示:
- 当然可以将服务器打包成jar包导入你的虚拟机
- 那么别人就可能通过客户端代码发送请求给你了~
- 不做演示~
3.3 socket文件怎么存储数据的
文章到此结束!谢谢观看 —>内容参考【比特科技】
可以叫我 小马,我可能写的不好或者有错误,但是一起加油鸭JavaEE 网络编程示例1 UDP套接字数据报编程 == 一发一收相关推荐
- 《网络编程》基本 UDP 套接字编程
在前面文章中介绍了<UDP 协议>和<套接字数据传输>.UDP 协议和 TCP 协议不同,它是一种面向无连接.不可靠的传输层协议.在基于 UDP 套接字编程中,数据传输可用函数 ...
- 《UNIX网络编程 卷1:套接字联网API(第3版)》——第2章 传输层:TCP、UDP和SCTP 2.1概述...
本节书摘来自异步社区<UNIX网络编程 卷1:套接字联网API(第3版)>一书中的第2章,第2.1节,作者:[美]W. Richard Stevens , Bill Fenner , An ...
- 【Linux网络编程】UDP 套接字编程
[Linux网络编程]UDP 套接字编程 [1]用户数据报协议(UDP) UDP是一个简单的传输层协议,不保证UDP数据报会到达其最终目的地,不保证各个数据报的先后顺序跨网络后保持不变,也不保证每个数 ...
- C++网络编程(二):UDP套接字编程
目录 基本特点 流程 基于UDP的数据I/O函数 UDP客户端套接字的地址分配 UDP套接字的数据边界 未连接UDP套接字.已连接UDP套接字 创建已连接UDP套接字 代码示例 参考资料 基本特点 U ...
- Linux IPv6 UDP套接字编程示例
udp ipv6套接字编程和ipv4接口类似,参数略有不同,流程都包括创建套接字.绑定地址.发送等. 下面是一个udp ipv6 demo, 包括创建ipv6套接字.绑定地址和发送数据等. 首先先在l ...
- Python之网络编程(TCP套接字与UDP套接字)
文章目录 基于tcp的套接字 实现目标 tcp服务端源码 tcp客户端源码 tcp效果实现 基于udp的套接字 udp作用介绍 udp服务端源码 udp客户端源码 udp效果实现 用udp实现一个时间 ...
- 【JavaEE】网络编程之TCP套接字、UDP套接字
目录 1.网络编程的基本概念 1.1为什么需要网络编程 1.2服务端与用户端 1.3网络编程五元组 1.4套接字的概念 2.UDP套接字编程 2.1UDP套接字的特点 2.2UDP套接字API 2.2 ...
- 网络编程---TCP/UDP套接字编程原理
本篇介绍的是Linux下的网络编程,故有些接口是不适用于Windows的,但是具体概念和实现方法是大体一致的 本篇重在讲解原理,具体实现请戳这里->UDP套接字编程实现 介绍 网络编程套接字(s ...
- 网络编程(part10)--socket套接字编程之UDP套接字
鄙人学习笔记 文章目录 UDP套接字编程 服务端流程 举个例子 客户端流程 举个例子 TCP套接字和UDP套接字编程区别 UDP套接字编程 服务端流程 创建数据报套接字 sockfd = socket ...
最新文章
- 开发者,什么是你真正关心的问题?| AI ProCon 2019
- 功能整合(二):轮播图(可控)、事件流
- Applicatin、 server、 session 、cookies对象的简单使用方法
- 【转】常见浏览器兼容性问题与解决方案css篇
- Java Review - 并发编程_ThreadLocalRandom实现原理源码分析
- HTML5学习笔记(五):CSS基础
- Android SQLite数据库 SQLiteOpenHelper的操作使用
- schema约束和引入
- 在使用node第三方模块dateformat中报错dateformat is not a function
- LeetCode 246. 中心对称数
- python换零钱有多少种方案_python练习题4.15换硬币(修正)
- visio画图复制粘贴到word_Visio 2010怎么复制图片 Visio粘贴图形到其它office程序
- ui sketch_如何在Sketch中设计汽车应用程序设计UI
- #93 高精度除低精度
- U盘文件全变快捷方式解决办法
- 【项目笔记_答题器】rp552d usb hid 在seewo win10 设备上启动无法识别
- 不是你需要中台,而是一名合格的架构师(附各中台建设PPT)
- 再聊聊Linux IO
- 关于DOS-BOX的使用方法
- 陷入多事之秋,阿里的价值观出问题了?
热门文章