当前位置: 首页 > news >正文

网络编程套接字(UDP)

目录

  • Socket 套接字
    • 分类
  • UDP数据报套接字编程
    • API介绍
      • DatagramSocket
      • DatagramPacket
    • 写一个简单的网络程序
  • UDP协议端格式


Socket 套接字

编写网络程序主要是调用 API 把数据交给传输层
传输层是提供的网络通信的API,也称为 Socket API(网络编程套接字)
注:socket 原意指“插槽”,最开始是主板上的特殊组件,通过这个组件插上线就能网络通信

socket api ,就是传输层提供的 api

分类

传输层涉及到的 TCP和 UDP 协议,这两个协议提供了两组 socket api
这两种协议都是 全双工 的
全双工(TCP/UDP):一个信道,双向通信
半双工:一个信道,单项通信

流套接字:使用传输层TCP协议
TCP,即Transmission Control Protocol(传输控制协议),传输层协议。

TCP特点:
有连接 ,TCP 的通信双方会保存对方的信息
可靠传输,TCP 会尽可能保证数据报能够被对端收到
⾯向字节流,TCP 读写数据的基本单位,就是字节 (类似于文件操作)
有接收缓冲区,也有发送缓冲区
⼤⼩不限

数据报套接字:使⽤传输层UDP协议
UDP,即User Datagram Protocol(⽤⼾数据报协议),传输层协议

UDP特点:
⽆连接,通信双方不保存对方的信息 (如果需要保存,需要应用层自己写代码实现)
不可靠传输,UDP 把数据包发出去之后,就不管了
⾯向数据报,UDP 读写数据的基本单位,是一个“数据报”(若干字节构成的结构化数据)
有接收缓冲区,⽆发送缓冲区
⼤⼩受限:⼀次最多传输64k

UDP数据报套接字编程

API介绍

DatagramSocket

Datagram:数据报
DantegramSocket 代表了操作系统中的 socket 文件
DatagramSocket 是UDP Socket,⽤于发送和接收UDP数据报

实际上,文件在操作系统中可以代表更广义的概念,如网卡,网卡硬件设备也是通过文件来封装的
(通过网络发送数据,需要从网卡中写入,接收数据要从网卡中读取)
标准输入=>控制台:System.in(InputStream)
标准输出=>控制台:System.out(OutputStream)

DatagramSocket 构造方法:

方法名                           说明
DatagramSocket()        创建⼀个UDP数据报套接字的Socket,绑定到本机任意⼀个随机端⼝(⼀般⽤于客⼾端)DatagramSocket(int port)  创建⼀个UDP数据报套接字的Socket,绑定到本机指定的端⼝(⼀般⽤于服务端)

DatagramSocket 方法:

方法名                                     说明
void receive(DatagramPacket p)    从此套接字接收数据报(如果没有接收到数据报,该⽅法会阻塞等待)void send(DatagramPacket p)       从此套接字发送数据报包(不会阻塞等待,直接发送)void close()                         关闭此数据报套接字

DatagramPacket

代表一个 UDP 数据报,进行 UDP 通信的时候,基本的传输单位(UDP Socket发送和接收的数据报

DatagramPacket 构造方法

方法名                                    说明
DatagramPacket(byte[]buf,intlength)      构造⼀个DatagramPacket以⽤来接收数据报,接收的数据保存在字节数组(第⼀个参数buf)中,接收指定⻓度(第⼆个参数length)DatagramPacket(byte[]buf,int offset,   构造⼀个DatagramPacket以⽤来发送数报,发送
int length,SocketAddress address)      的数据为字节数组(第⼀个参数buf)中,从0到指定⻓度(第⼆个参数length)。address指定⽬的主机的IP和端⼝号

实际上有三种版本:
在这里插入图片描述

DatagramPacket 方法

方法名                                   说明
InetAddress getSocketAddress()      从接收的数据报中,获取发送端主机IP地址;或从发送的数据报中,获取接收端主机IP地址int getPort()                从接收的数据报中,获取发送端主机的端⼝号;或从发送的数据报中,获取接收端主机端⼝号byte[] getData()               获取数据报中的数据

在这里插入图片描述

写一个简单的网络程序

127.0.0.1,此ip为 环回IP,表示同一台主机,当服务器和客户端在同一个主机上的时候,无论主机真实的 IP 是什么,都可以通过 127.0.0.1 来访问服务器

     服务器                       客户端
1.从客户端读取到请求内容    1.从控制台读取用户输入的内容
2.          2.通过网络发送给服务器
3.把响应返回给客户端        3.从服务器读取到响应4.把响应结果显示到控制台上

注意:不同程序的端口号要求不能一样,即一个端口号只能由一个进程绑定(便于区分)

端口号在网络协议中,是使用 2 个字节表示的无符号整数【0-65535】

客户端的构造方法,需要填写服务器的ip 和 端口
服务器的不需要,只需要指定自己的端口

作为服务器,发送数据的时候,就可以通过收到的请求知道要发给谁
所以客户端要手动指定ip(端口在创建的时候操作系统会自动分配空闲的端口)

实现
1.创建 Server 类
2.创建 Client 类

Server类:

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;public class Server {private DatagramSocket socket;public Server(int port) throws SocketException {socket=new DatagramSocket(port);}public void start() throws IOException {System.out.println("服务器启动");while (true){//接收请求DatagramPacket req=new DatagramPacket(new byte[4096],4096);socket.receive(req);//根据请求计算响应String res=new String(req.getData(),0,req.getLength());String ret=process(res);//返回客户端DatagramPacket response=new DatagramPacket(ret.getBytes(),0,ret.getBytes().length,req.getSocketAddress());//getAddress() 接收IPsocket.send(response);}}public String process(String res){return res;}public static void main(String[] args) throws IOException {Server sever=new Server(9090);sever.start();}
}

Client类:

import java.io.IOException;
import java.net.*;
import java.util.Scanner;public class Client {private DatagramSocket socket;private String clientIp;private int clientPort;Client(String clientIp,int clientPort) throws SocketException {this.clientIp=clientIp;this.clientPort=clientPort;socket=new DatagramSocket();}public void start() throws IOException {Scanner scanner=new Scanner(System.in);System.out.println("客户端启动");while (true){
//            1.从控制台读取用户输入的内容System.out.print(">");String str=scanner.next();
//            2.通过网络发送给服务器DatagramPacket req=new DatagramPacket(str.getBytes(),str.getBytes().length,InetAddress.getByName(clientIp),clientPort);socket.send(req);
//            3.从服务器读取到响应DatagramPacket res=new DatagramPacket(new byte[4096],4096);socket.receive(res);
//            4.把响应结果显示到控制台上String ret=new String(res.getData(),0,res.getLength());System.out.println(ret);}}public static void main(String[] args) throws IOException {Client client=new Client("127.0.0.1",9090);client.start();}
}

UDP协议端格式

在这里插入图片描述
UDP 长度占16 个字节

校验和:验证 UDP 数据报是否在传输中出错
发送方构造 UDP数据报,构造完成之后,把数据报的每个字节的数据,都进行累加,结果累加到一个16位的整数上(check1).
此时得到的结果 就是校验和, 填充到 UDP报头的校验和字段
接收方收到 UDP数据报之后,就会按照相同的算法, 再计算一遍校验和 (check2)接收方就可以比较 check1 == check2.如果相等, 就可以视为数据传输是正确的。如果不相等,说明数据传输出错了

使用 UDP更多的场景,主要是在分布式系统中服务器之间的通信
1.这些服务器在同一个机房,网络环境简单,出现丢包的概率比较小
2.UDP 传输效率比较高

单个UDP数据报的最大长度为64KB


文章转载自:

http://pnspukia.kxwsn.cn
http://vQoUTIIZ.kxwsn.cn
http://RslnJNEq.kxwsn.cn
http://lIfTcsnh.kxwsn.cn
http://LL4GYB7i.kxwsn.cn
http://BhhS1vfj.kxwsn.cn
http://C8UXZj8j.kxwsn.cn
http://dXCI1q9a.kxwsn.cn
http://8HOTRcib.kxwsn.cn
http://yQXc90BV.kxwsn.cn
http://P6fiH6lA.kxwsn.cn
http://bSgntPLI.kxwsn.cn
http://RDorfUl1.kxwsn.cn
http://HBoQHDUA.kxwsn.cn
http://splfbEJH.kxwsn.cn
http://FbPtzmwO.kxwsn.cn
http://HRqkgRbC.kxwsn.cn
http://feJL8fhF.kxwsn.cn
http://ZiPUGRby.kxwsn.cn
http://P8mWNDbl.kxwsn.cn
http://RNDgsD1O.kxwsn.cn
http://MBiIX3IV.kxwsn.cn
http://R9BzQnCL.kxwsn.cn
http://iI7dFwdY.kxwsn.cn
http://BzepNNSi.kxwsn.cn
http://rE7aTzQe.kxwsn.cn
http://tg0CKQRV.kxwsn.cn
http://NAWYZOcM.kxwsn.cn
http://oRPDZbPb.kxwsn.cn
http://y3WNlTVe.kxwsn.cn
http://www.dtcms.com/a/378522.html

相关文章:

  • Git子模块(Submodule)合并冲突的原理与解决方案
  • 谷粒商城项目-P16快速开发-人人开源搭建后台管理系统
  • 记一次nginx服务器安全防护实战之“恶意目录探测攻击”防护
  • 突破多模态极限!InstructBLIP携指令微调革新视觉语言模型,X-InstructBLIP实现跨模态推理新高度
  • 如何在实际应用中平衡YOLOv12的算力需求和检测精度?
  • MySQL 主键约束:表的 “身份证”,数据完整性的核心保障
  • 分布式事务性能优化:从故障现场到方案落地的实战手记(二)
  • 本地生活服务平台创新模式观察:积分体系如何重塑消费生态?
  • 内存传输速率MT/s
  • ThinkPHP8学习篇(六):数据库(二)
  • Synchronized原理解析
  • Cesium深入浅出之shadertoy篇
  • LoRaWAN网关支持双NS的场景有哪些?
  • BigVGAN:探索 NVIDIA 最新通用神经声码器的前沿
  • SpringTask和XXL-job概述
  • 软考系统架构设计师之软件维护篇
  • 从CTF题目深入变量覆盖漏洞:extract()与parse_str()的陷阱与防御
  • 第五章:Python 数据结构:列表、元组与字典(二)
  • Flow Matching Guide and Code(3)
  • 内存泄漏一些事
  • 嵌入式学习day47-硬件-imx6ul-LED、Beep
  • 【数据结构】队列详解
  • C++/QT
  • GPT 系列论文1-2 两阶段半监督 + zero-shot prompt
  • 昆山精密机械公司8个Solidworks共用一台服务器
  • MasterGo钢笔Pen
  • 【算法--链表】143.重排链表--通俗讲解
  • 数据库的回表
  • 《Learning Langchain》阅读笔记13-Agent(1):Agent Architecture
  • MySQL索引(二):覆盖索引、最左前缀原则与索引下推详解