TCP/IP协议以及UDP(超详细,看这一篇就够了)

💓 博客主页:从零开始的-CodeNinja之路

⏩ 收录专栏:TCP/IP协议以及UDP(超详细,看这一篇就够了)

🎉欢迎大家点赞👍评论📝收藏⭐文章

TCP/IP协议以及UDP(超详细,看这一篇就够了

    • 前提概括
        • 接收端和发送端
        • 客户端和服务端
        • 客户端和服务端交流过程
  • 一: TCP协议
      • 1.1:TCP协议的六大特性
      • 1.2:Socket
      • 1.3:ServerSocket
      • 1.4:TCP的实现
        • TCP Echo Server服务器
        • TCP Echo Client客服端
  • 二: UDP协议
      • 2.1:UDP协议的六大特特性
      • 2.2:DatagramSocket
      • 2.3:DatagramPacket
      • 2.4:UDP的实现
        • UDP Echo Server服务器
        • UDP Echo Client客服端

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

前提概括

首先进入本章知识重点之前,我们要先了解清楚计算机在客户端以及服务端扮演的角色以及交流过程.

接收端和发送端

在⼀次网络数据传输时:
发送端:数据的发送方进程,称为发送端。发送端主机即网络通信中的源主机。
接收端:数据的接收方进程,称为接收端。接收端主机即网络通信中的目的主机。
注意:发送端和接收端只是相对的,只是⼀次网络数据传输产生数据流向后的概念。

客户端和服务端

服务端:在常见的网络数据传输场景下,把提供服务的一方进程,称为服务端,可以提供对外服务。
客户端:获取服务的一方进程,称为客户端。

客户端和服务端交流过程

最常见的场景,客户端是指给用户使用的程序,服务端是提供用户服务的程序:

  1. 客户端先发送请求到服务端
  2. 服务端根据请求数据,执行相应的业务处理
  3. 服务端返回响应:发送业务处理结果
  4. 客户端根据响应数据,展示处理结果(展示获取的资源,或提示保存资源的处理结果). 在这里插入图片描述

一: TCP协议

传输层TCP协议
TCP,即Transmission Control Protocol(传输控制协议),传输层协议

1.1:TCP协议的六大特性

  • 有连接
  • 双全工
  • 可靠传输
  • 面向字节流
  • 有接收缓冲区,也有发送缓冲区
  • 大小不限

对于字节流来说,可以简单的理解为,传输数据是基于IO流,流式数据的特征就是在IO流没有关闭的
情况下,是无边界的数据,可以多次发送,也可以分开多次接收

1.2:Socket

Socket 是客户端Socket,或服务端中接收到客户端建立连接(accept方法)的请求后,返回的服
务端Socket。
不管是客户端还是服务端Socket,都是双方建立连接以后,保存的对端信息,及用来与对方收发数据
的。

⽅法签名⽅法说明
Socket(String host,int port)创建⼀个客户端流套接字Socket,并与对应IP的主机上,对应端口的进程建立连接

Socket 方法:

⽅法签名⽅法说明
InetAddress getInetAddress()返回套接字所连接的地址
InputStream getInputStream()返回此套接字的输入流
OutputStream getOutputStream()返回此套接字的输出流

1.3:ServerSocket

ServerSocket 是创建TCP服务端Socket的API。
ServerSocket 构造方法:

⽅法签名⽅法说明
ServerSocket(int port)创建⼀个服务端流套接字Socket,并绑定到指定端口

ServerSocket 方法:

⽅法签名⽅法说明
Socket accept()开始监听指定端口(创建时绑定的端口),有客户端连接后,返回⼀个服务端Socket对象,并基于该Socket建立与客户端的连接,否则阻塞等待
void close()关闭此套接字

1.4:TCP的实现

  1. 客户端和服务端:开发时,经常是基于⼀个主机开启两个进程作为客户端和服务端,但真实的场
    景,⼀般都是不同主机。
  2. 注意目的IP和目的端口号,标识了⼀次数据传输时要发送数据的终点主机和进程
  3. Socket编程我们是使用流套接字和数据报套接字,基于传输层的TCP或UDP协议,但应用层协议,
    也需要考虑,这块我们在后续来说明如何设计应用层协议。
  4. 关于端口被占用的问题
  5. 如果⼀个进程A已经绑定了⼀个端口,再启动⼀个进程B绑定该端口,就会报错,这种情况也叫端口
    被占用。对于java进程来说,端口被占用的常见报错信息如下:
    在这里插入图片描述
TCP Echo Server服务器
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;public class TcpEchoServer {private ServerSocket serverSocket = null;// 这个操作就会绑定端⼝号public TcpEchoServer(int port) throws IOException {serverSocket = new ServerSocket(port);}// 启动服务器public void start() throws IOException {System.out.println("服务器启动!");while (true) {Socket clientSocket = serverSocket.accept();processConnection(clientSocket);}}// 通过这个⽅法来处理⼀个连接的逻辑.private void processConnection(Socket clientSocket) {System.out.printf("[%s:%d] 客⼾端上线!\n", clientSocket.getInetAddress().t
// 接下来就可以读取请求, 根据请求计算响应, 返回响应三步⾛了.
// Socket 对象内部包含了两个字节流对象, 可以把这俩字节流对象获取到, 完成后续的读写try (InputStream inputStream = clientSocket.getInputStream();OutputStream outputStream = clientSocket.getOutputStream()) {
// ⼀次连接中, 可能会涉及到多次请求/响应while (true) {
// 1. 读取请求并解析. 为了读取⽅便, 直接使⽤ Scanner.Scanner scanner = new Scanner(inputStream);if (!scanner.hasNext()) {
// 读取完毕, 客⼾端下线.System.out.printf("[%s:%d] 客⼾端下线!\n", clientSocket.getInebreak;}
// 这个代码暗含⼀个约定, 客⼾端发过来的请求, 得是⽂本数据, 同时, 还得带有String request = scanner.next();
// 2. 根据请求计算响应String response = process(request);
// 3. 把响应写回给客⼾端. 把 OutputStream 使⽤ PrinterWriter 包裹⼀下PrintWriter writer = new PrintWriter(outputStream);
// 使⽤ PrintWriter 的 println ⽅法, 把响应返回给客⼾端.
// 此处⽤ println, ⽽不是 print 就是为了在结尾加上 \n . ⽅便客⼾端writer.println(response);
// 这⾥还需要加⼀个 "刷新缓冲区" 操作.writer.flush();
// ⽇志, 打印当前的请求详情.System.out.printf("[%s:%d] req: %s, resp: %s\n", clientSocket.gerequest, response);}} catch (IOException e) {e.printStackTrace();} finally {
// 在 finally 中加上 close 操作, 确保当前 socket 被及时关闭!!try {clientSocket.close();} catch (IOException e) {e.printStackTrace();}}}public String process(String request) {return request;}public static void main(String[] args) throws IOException {TcpEchoServer server = new TcpEchoServer(9090);server.start();}
}
TCP Echo Client客服端
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;public class TcpEchoClient {private Socket socket = null;// 要和服务器通信, 就需要先知道, 服务器所在的位置.public TcpEchoClient(String serverIp, int serverPort) throws IOException {
// 这个 new 操作完成之后, 就完成了 tcp 连接的建⽴.socket = new Socket(serverIp, serverPort);}public void start() {System.out.println("客⼾端启动");Scanner scannerConsole = new Scanner(System.in);try (InputStream inputStream = socket.getInputStream();OutputStream outputStream = socket.getOutputStream()) {while (true) {
// 1. 从控制台输⼊字符串.System.out.print("-> ");String request = scannerConsole.next();
// 2. 把请求发送给服务器PrintWriter printWriter = new PrintWriter(outputStream);
// 使⽤ println 带上换⾏. 后续服务器读取请求, 就可以使⽤ scanner.nprintWriter.println(request);
// 不要忘记 flush, 确保数据是真的发送出去了!!printWriter.flush();
// 3. 从服务器读取响应.Scanner scannerNetwork = new Scanner(inputStream);String response = scannerNetwork.next();
// 4. 把响应打印出来System.out.println(response);}} catch (IOException e) {e.printStackTrace();}}public static void main(String[] args) throws IOException {TcpEchoClient client = new TcpEchoClient("127.0.0.1", 9090);client.start();}
}

二: UDP协议

传输层UDP协议
UDP,即User Datagram Protocol(用户数据报协议),传输层协议。

2.1:UDP协议的六大特特性

  • 无连接
  • 双全工
  • 不可靠传输
  • 面向数据报
  • 有接收缓冲区,无发送缓冲区
  • 大小受限:⼀次最多传输64k

对于数据报来说,可以简单的理解为,传输数据是⼀块⼀块的,发送⼀块数据假如100个字节,必须⼀
次发送,接收也必须⼀次接收100个字节,而不能分100次,每次接收1个字节。

2.2:DatagramSocket

DatagramSocket 是UDP Socket,用于发送和接收UDP数据报。

DatagramSocket 构造方法

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

DatagramSocket 方法

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

2.3:DatagramPacket

DatagramPacket是UDP Socket发送和接收的数据报。
DatagramPacket 构造方法:

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

DatagramPacket 方法:

⽅法签名⽅法说明
InetAddress getAddress()从接收的数据报中,获取发送端主机IP地址;或从发送的数据报中,获取接收端主机IP地址
int getPort()从接收的数据报中,获取发送端主机的端口号;或从发送的数据报中,获取接收端主机端⼝号
byte[] getData()获取数据报中的数据构造UDP发送的数据报时

2.4:UDP的实现

对于UDP协议来说,具有无连接,面向数据报的特征,即每次都是没有建立连接,并且⼀次发送全部
数据报,⼀次接收全部的数据报。
java中使用UDP协议通信,主要基于 DatagramSocket 类来创建数据报套接字,并使用
DatagramPacket 作为发送或接收的UDP数据报。对于⼀次发送及接收UDP数据报的流程如下:
在这里插入图片描述

UDP Echo Server服务器
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.SocketException;public class UdpEchoServer {private DatagramSocket socket = null;// 参数是服务器要绑定的端⼝public UdpEchoServer(int port) throws SocketException {socket = new DatagramSocket(port);}// 使⽤这个⽅法启动服务器.public void start() throws IOException {System.out.println("服务器启动!");while (true) {
// 反复的, ⻓期的执⾏针对客⼾端请求处理的逻辑.
// ⼀个服务器, 运⾏过程中, 要做的事情, 主要是三个核⼼环节.
// 1. 读取请求, 并解析DatagramPacket requestPacket = new DatagramPacket(new byte[4096], 40socket.receive(requestPacket);
// 这样的转字符串的前提是, 后续客⼾端发的数据就是⼀个⽂本的字符串.String request = new String(requestPacket.getData(), 0, requestPacke
// 2. 根据请求, 计算出响应String response = process(request);
// 3. 把响应写回给客⼾端
// 此时需要告知⽹卡, 要发的内容是啥, 要发给谁.DatagramPacket responsePacket = new DatagramPacket(response.getBytesrequestPacket.getSocketAddress());socket.send(responsePacket);
// 记录⽇志, ⽅便观察程序执⾏效果.System.out.printf("[%s:%d] req: %s, resp: %s\n", requestPacket.getAdrequest, response);}}// 根据请求计算响应. 由于是回显程序, 响应内容和请求完全⼀样.public String process(String request) {return request;}public static void main(String[] args) throws IOException {UdpEchoServer server = new UdpEchoServer(9090);server.start();}
}
UDP Echo Client客服端
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.util.Scanner;public class UdpEchoClient {private DatagramSocket socket = null;private String serverIp;private int serverPort;// 服务器的 ip 和 服务器的端⼝.public UdpEchoClient(String ip, int port) throws SocketException {serverIp = ip;serverPort = port;
// 这个 new 操作, 就不再指定端⼝了. 让系统⾃动分配⼀个空闲端⼝.socket = new DatagramSocket();}// 让这个客⼾端反复的从控制台读取⽤⼾输⼊的内容. 把这个内容构造成 UDP 请求, 发给服务器
// 最终再显⽰在客⼾端的屏幕上.public void start() throws IOException {Scanner scanner = new Scanner(System.in);System.out.println("客⼾端启动!");while (true) {
// 1. 从控制台读取⽤⼾输⼊的内容System.out.print("-> "); // 命令提⽰符, 提⽰⽤⼾要输⼊字符串.String request = scanner.next();
// 2. 构造请求对象, 并发给服务器.DatagramPacket requestPacket = new DatagramPacket(request.getBytes()InetAddress.getByName(serverIp), serverPort);socket.send(requestPacket);
// 3. 读取服务器的响应, 并解析出响应内容.DatagramPacket responsePacket = new DatagramPacket(new byte[4096], 4socket.receive(responsePacket);String response = new String(responsePacket.getData(), 0, responsePa
// 4. 显⽰到屏幕上.System.out.println(response);}}public static void main(String[] args) throws IOException {UdpEchoClient client = new UdpEchoClient("127.0.0.1", 9090);
// UdpEchoClient client = new UdpEchoClient("42.192.83.143", 9090);client.start();}
}

在这里插入图片描述
如果觉得文章不错,期待你的一键三连哦,你个鼓励是我创作的动力之源,让我们一起加油,顶峰相见!!!💓 💓 💓

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/254308.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【数据分享】1929-2023年全球站点的逐月平均能见度(Shp\Excel\免费获取)

气象数据是在各项研究中都经常使用的数据,气象指标包括气温、风速、降水、能见度等指标,说到气象数据,最详细的气象数据是具体到气象监测站点的数据! 之前我们分享过1929-2023年全球气象站点的逐月平均气温数据、逐月最高气温数据…

CSP-202112-1-序列查询

CSP-202112-1-序列查询 提示:若存在区间[i,j) 满足:f(i)f(i1)…f(j-1),使用乘法运算 f(i)x(j-i)代替将 f()到 f(j- 1)逐个相加,或可大幅提高算法效率。 一定要看提示!单纯的模拟时间会超限!算法也是根据提示设计的。 …

【Web】vulhub Fastjson反序列化漏洞复现学习笔记

目录 1.2.24 RCE CVE-2017-18349 复现流程 原理分析 1.2.47 RCE CNVD-2019-22238 复现流程 原理分析 漏洞探测 1.2.24 RCE CVE-2017-18349 复现流程 vulhub启动靶场 用marshalsec启动LDAP/RMI服务 java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.LDAPRef…

【每日一题】LeetCode——链表的中间结点

📚博客主页:爱敲代码的小杨. ✨专栏:《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 ❤️感谢大家点赞👍🏻收藏⭐评论✍🏻,您的三连就是我持续更新的动力❤️ 🙏小杨水平有…

LabVIEW网络测控系统

LabVIEW网络测控系统 介绍了基于LabVIEW的网络测控系统的开发与应用,通过网络技术实现了远程的数据采集、监控和控制。系统采用LabVIEW软件与网络通信技术相结合,提高了系统的灵活性和扩展性,适用于各种工业和科研领域的远程测控需求。 随着…

机器学习:回归决策树(Python)

一、平方误差的计算 square_error_utils.py import numpy as npclass SquareErrorUtils:"""平方误差最小化准则,选择其中最优的一个作为切分点对特征属性进行分箱处理"""staticmethoddef _set_sample_weight(sample_weight, n_samp…

FlinkSql 窗口函数

Windowing TVF 以前用的是Grouped Window Functions(分组窗口函数),但是分组窗口函数只支持窗口聚合 现在FlinkSql统一都是用的是Windowing TVFs(窗口表值函数),Windowing TVFs更符合 SQL 标准且更加强大…

第5章 数据库操作

学习目标 了解数据库,能够说出数据库的概念、特点和分类 熟悉Flask-SQLAlchemy的安装,能够在Flask程序中独立安装扩展包Flask-SQLAlchemy 掌握数据库的连接方式,能够通过设置配置项SQLALCHEMY_DATABASE_URI的方式连接数据库 掌握模型的定义…

rust语言tokio库底层原理解析

目录 1 rust版本及tokio版本说明1 tokio简介2 tokio::main2.1 tokio::main使用多线程模式2.2 tokio::main使用单线程模式 3 builder.build()函数3.1 build_threaded_runtime()函数新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图…

【开源】JAVA+Vue.js实现高校实验室管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容2.1 实验室类型模块2.2 实验室模块2.3 实验管理模块2.4 实验设备模块2.5 实验订单模块 三、系统设计3.1 用例设计3.2 数据库设计 四、系统展示五、样例代码5.1 查询实验室设备5.2 实验放号5.3 实验预定 六、免责说明 一、摘…

使用 Docker 镜像预热提升容器启动效率详解

概要 在容器化部署中,Docker 镜像的加载速度直接影响到服务的启动时间和扩展效率。本文将深入探讨 Docker 镜像预热的概念、必要性以及实现方法。通过详细的操作示例和实践建议,读者将了解如何有效地实现镜像预热,以加快容器启动速度,提高服务的响应能力。 Docker 镜像预热…

【数据结构】堆(创建,调整,插入,删除,运用)

目录 堆的概念: 堆的性质: 堆的存储方式: 堆的创建 : 堆的调整: 向下调整: 向上调整: 堆的创建: 建堆的时间复杂度: 向下调整: 向上调整&#xff…

红队打靶练习:GLASGOW SMILE: 1.1

目录 信息收集 1、arp 2、nmap 3、nikto 4、whatweb 目录探测 1、gobuster 2、dirsearch WEB web信息收集 /how_to.txt /joomla CMS利用 1、爆破后台 2、登录 3、反弹shell 提权 系统信息收集 rob用户登录 abner用户 penguin用户 get root flag 信息收集…

HARRYPOTTER: FAWKES

攻击机 192.168.223.128 目标机192.168.223.143 主机发现 nmap -sP 192.168.223.0/24 端口扫描 nmap -sV -p- -A 192.168.223.143 开启了21 22 80 2222 9898 五个端口,其中21端口可以匿名FTP登录,好像有点说法,百度搜索一下发现可以用anonymous登录…

网络安全产品之认识准入控制系统

文章目录 一、什么是准入控制系统二、准入控制系统的主要功能1. 接入设备的身份认证2. 接入设备的安全性检查 三、准入控制系统的工作原理四、准入控制系统的特点五、准入控制系统的部署方式1. 网关模式2. 控制旁路模式 六、准入控制系统的应用场景七、企业如何利用准入控制系统…

使用PDFBox实现pdf转其他图片格式

最近在做一个小项目&#xff0c;项目中有一个功能要把pdf格式的图片转换为其它格式&#xff0c;接下来看看用pdfbox来如何实现吧。 首先导入pdfbox相关依赖&#xff1a; <dependency> <groupId>org.apache.pdfbox</groupId> <artifactId>pdfbox</a…

【高阶数据结构】位图布隆过滤器

文章目录 1. 位图1.1什么是位图1.2为什么会有位图1.3 实现位图1.4 位图的应用 2. 布隆过滤器2.1 什么是布隆过滤器2.2 为什么会有布隆过滤器2.3 布隆过滤器的插入2.4 布隆过滤器的查找2.5 布隆过滤器的模拟实现2.6 布隆过滤器的优点2.7 布隆过滤器缺陷 3. 海量数据面试题3.1 哈…

CTFshow web(命令执行29-36)

?ceval($_GET[shy]);&shypassthru(cat flag.php); #逃逸过滤 ?cinclude%09$_GET[shy]?>&shyphp://filter/readconvert.base64-encode/resourceflag.php #文件包含 ?cinclude%0a$_GET[cmd]?>&cmdphp://filter/readconvert.base64-encode/…

Kubernetes实战(二十七)-HPA实战

1 HPA简介 HPA 全称是 Horizontal Pod Autoscaler&#xff0c;用于POD 水平自动伸缩&#xff0c; HPA 可以 基于 POD CPU 利用率对 deployment 中的 pod 数量进行自动扩缩容&#xff08;除了 CPU 也可以基于自定义的指标进行自动扩缩容&#xff09;。pod 自动缩放不适用于无法…

ubuntu22.04@laptop OpenCV Get Started: 001_reading_displaying_write_image

ubuntu22.04laptop OpenCV Get Started: 001_reading_displaying_write_image 1. 源由2. Read/Display/Write应用Demo2.1 C应用Demo2.2 Python应用Demo 3. 过程分析3.1 导入OpenCV库3.2 读取图像文件3.3 显示图像3.4 保存图像文件 4. 总结5. 参考资料 1. 源由 读、写、显示图像…