复习总结最终版:计算机网络
一、网络基础概念、抓包
(一)网络通信目的:实现不同主机间信息交换和资源共享
(二)IP地址(IPV4,即将用尽以后用IPV6替代)
1.概念:用来唯一的标识一台主机
2.ip地址:192.168.0.168
3.子网掩码:255.255.255.0
4.默认网关:192.168.0.1
5.IP = 网络号+主机号
6.ip(IPV4)本质为32位的二进制数,用点分十进制转换而来
7.子网掩码与ip地址相与来区分网络
(三)www.baidu.com-->DNS(域名解析)-->183.2.172.17
(四)wireshark抓包过程
1.sudo wireshark启动
2.双击ens33/any查看
3.过滤,条形框输入过滤条件或者expression过滤
4.鼠标右击跟随想了解的内容查看
5.SYN和ACK查看
二、网络模型(理解通信层次)
(一)TCP/IP五层模型:当今互联网真正遵循的架构
1.应用层:为应用程序提供网络接口(信的内容,你要说什么) //http,SMTP(邮件传输),FTP(文件传输)
2.传输层:进程到进程的通信,负责可靠性(装信封,写地址,确保信能送到具体的人(端口号)手中) //TCP(可靠),UDP(高效)
3.网络层:主机到主机的通信,负责寻址(邮政系统,根据地址(ip)决定信走那条路,最终送到那个主机) //IP协议,路由器
4.数据链路层:提供同一局域网内相邻设备的帧传输(大楼的收发室,负责把信交给打楼的具体房间(MAC地址)) //以太网,MAC地址
5.物理层:传输原始bit流(0和1) //网线,光纤
(二)OSI七层模型(开放的系统互联模型):理论框架
在应用层和传输层添加了:表示层 //压缩、加密
:会话层 //管理一次通信过程
三、socket
(一)理解:是操作系统提供的API(应用程序编程接口)。网络上的门,数据通过它进出。
(二)socket = IP地址 + 端口号
(三)作用
1.IPC
2.网络通信:不同计算机上的进程可以通过socket进行数据交换
(四)类型
1.流式socket(SOCK_STREAM):基于TCP,提供可靠、面向连接的字节流传输
2.数据报socket(SOCK_DGRAM):基于UDP,无连接、不可靠的数据报传输
(五)TCP Socket
1.server
①创建Socket:socket()
②绑定IP和端口:bind
③监听连接:listen() //用来建立连接
④接收客户端连接:accept() //
⑤收发数据:send()/recv()
⑥关闭:close()
2.client
①创建Soclkt:socket()
②连接服务器:connect() //
③收发数据:send()/recv()
④关闭连接:close()
(六)UDP Socket:因为UDP无连接,所以不需要listen()和accept(),直接收发数据即可
1.server
①创建Soclkt:socket()
②绑定IP和端口:bind
③收发数据:sendto()/recvfrom()
④关闭连接:close()
2.client
①创建Soclkt:socket()
②收发数据:sendto()/recvfrom()
③关闭连接:close()
四、TCP(粘包问题)、天气预报
(一)TCP粘包问题
1.TCP粘包是什么?
指发送方发送的多个数据包在接收方接受时(缓存区数据堆积)被合并成一个大的数据包的现象。
这是由于TCP协议本身特性导致的,TCP是面向字节流的协议,在数据传输过程没有明确的边界
2.解决方法
①消息边界:在每次发完消息后,添加特殊字符(\r\n)表示消息的边界。这需要接收端在应用层自行处理
②发送固定定大小的数据
③结构体:自定义结构体(head、body)
typedef struct Msg
{
int type; //交互约定
char buf[256]; //内容
}msg_t;
3.柔性数组:没定义数组元素个数,c99中它会动态分配内存
(二)TCP(传输控制协议)
1.有连接(三次握手,四次挥手)
握手 ①cli-->ser:SYN=1, seq=x (客户端:我想建立连接,我的初始序号是x)
②cli<--ser:SYN=1, ACK=1, seq=y, ack=x+1 (服务器:我同意建立连接,你的x我收到了,我的初始序号是y)
③cli-->ser:ACK=1, seq=x+1, ack=y+1 (客户端:好的,你的y我也收到了,开始通信吧)
挥手 ①主动方-->被动方:FIN=1, seq=u (主动方:我的数据发完了,要关闭连接)
②主动方<--被动方:ACK=1, ack=u+1 (被动方:我知道你要关了)(此时连接处于半关闭状态,被动方可能还有数据要发送)
③主动方<--被动方:FIN=1, ACK=1, seq=v, ack=u+1 (被动方:我的数据也发完了,我也要关了)
④主动方-->被动方:ACK=1, ack=v+1 (主动方:好的,彻底关闭吧)
2.可靠传输:数据不丢失、不重复、不乱序
①确认应答(ACK):接收方每收到一个数据包,都会发送一个确认(ACK)给发送方
②超时重传:发送方发送一个数据包后启动定时器。如果在规定时间内没收到对应的ACK,就认为数据包丢失,会重新发送。
③序列号与确认号:每个字节的数据都会被分配一个序列号。
ACK号告诉发送方“我期望收到的下一个数据的序列号是多少”,这样既能确认接收,也能保证顺序。
3.面向字节流:无明确边界、缓冲区积累数据会发生粘包问题
4.流量控制(滑动窗口):防止发送方发送速度过快,导致接收方缓冲区溢出
实现机制:接收方在ACK包中通告自己的接收窗口大小,发送方根据这个窗口大小调整发送速率。
5.拥塞控制(21-图):防止发送方发送速度过快,导致网络中间节点(如路由器)过载,引发网络瘫痪
实现机制:包括慢启动、拥塞避免、快速重传、快速恢复等算法。TCP 通过感知网络拥塞程度(如丢包)来动态调整自己的发送窗口。
(三)天气预报
1.预期结果:程序运行输入所要查询的地点,然后出现三个选项实时天气、未来天气、生活指数。
2.实现思路:Ubuntu中利用NOWapi服务器获取访问数据api地址,然后创建客户端利用TCP、IPV4协议分别访问实时天气,未来天气,生活指数api地址。
F12可以获取到信息,然后将api数据中appkey改用自己账号的即可。
如果账号到期可以用字符串数组搞一个欺骗行为,伪装为浏览器网址访问然后获取信息。
3.数据分割:strtok函数,先将字符串数组strcpy到另一个数组,然后每次分割后将原字符串再一次复制到使用的数组中,这样字符串数组就不会被破坏
五、TCP与UDP对比
TCP(打电话) UDP(广播)
连接 面向连接 无连接
可靠性 高可靠性 不可靠
数据传输 字节流(无可靠边界) 数据报(有边界的独立数据包)
速度 慢(延迟高、开销大) 块(延迟低、开销小)
头部大小 大(20-60字节) 小(8字节)
应用 HTTP、SMPT、FTP 视频会议
流量控制
拥塞控制(慢启动、拥塞避免)
六、UDP、聊天室
(一)UDP(用户数据报协议)
1.无连接:发送数据前不需要建立连接
2.尽最大努力交付:不保证数据包一定能到达接收方。如果因为网络原因丢失,UDP 协议本身不会负责重传
3.面向报文:应用程序交给 UDP 多长的报文,UDP 就原样发送,一次发送一个完整的报文,并保留这些边界
4.无拥塞控制:不管网络是否拥堵,UDP 都会以恒定的速率发送数据
①缺点是会加剧网络拥塞
②优点是不会因为拥塞而主动降低发送速率,延迟稳定
(二)UDP聊天室
1.预期结果:多个用户可以一起聊天,当用户加入/退出聊天室,聊天室每个成员都可以看到加入/退出用户的信息。
2.client
①使用socket函数接口并且建立客户端地址信息
②定义使用结构体和枚举,发送和接收直接用结构体。枚举用户状态(sigin、chat、quit),结构体(用户状态、用户昵称,用户消息)
③用户加入时:向服务器发送登录状态
④聊天过程:创建两个线程执行发送和接收服务器发送过来的消息
⑤退出时:通过发送线程,向服务器发送quit作为退出标志
3.server
①使用socket函数接口并且绑定服务器地址信息
②定义同样的结构体来接收信息。因为服务器需要向每个在线的客户端发送结构体信息,所以需要保存加入的客户端地址信息。这里则还需要定义一个结构体来存放地址信息和用户的状态。
③接收客户端发来的信息判断信息状态后执行操作。
a.服务器接收的客户端状态为sigin:发送信息给每一个在线的客户端(可以将存在的客户端信息存在链表(数组)里面,然后遍历链表判断状态,发给每一个在线的客户端),将自己的地址尾插法插入链表(发送之后插入可以不用判断自己)。
b.接收到的客户端信息为chat:发送消息给除自己之外的每一个客户端
c.接收到的客户端信息为quit:发送给除自己每个用户之后,删除这个用户所在链表节点
4.遇到的问题
①是什么:客户端定义的结构体全局变量msg,在主函数中输入msg.name,而在发送线程调用但msg.name没有被赋值。
②为什么:线程共享进程内存数据区,而定义的全局变量是他们俩共享的区域。
如果recv接收到服务端发来的msg,则原本进程中结构体msg整体会被覆盖
(我在recvfrom之前还bzero清除了结构体),所以导致sendto线程中msg.nsme没有值
③怎么办:先检查,因为当局者迷,所以找不出来。AI直接问了2个多小时为什么,分析不出来。
出去理发的时候,才想起来可不可以把这个客户端全部代码发给AI它能不能分析出来。
回来拍代码发给它,一下就找到原因了。
//定义一个专门保存msg.name的全局变量,在主函数赋值后,在sendto时每次将取出来赋值给msg.nsme
七、HTTP
(一)万维网
1.定义:是一个由无数个互相链接的文档(网页)和其他资源组成的全球性信息系统。这些资源通过超链接相互关联,并通过 URL 进行定位,利用 HTTP 协议进行访问。
2.万维网的三大基石:URL、HTTP、HTML
①URL(统一资源定位符):它是互联网上每个资源(网页、图片、视频)的唯一地址
一般形式:协议://主机名:端口号/路径
②HTTP(超文本传输协议):定义了客户端(浏览器)和服务器之间如何通信的规则
③HTML(超文本标记语言):它是一种用于创建网页的标记语言,定义了网页的内容(文字、图片)和结构(标题、段落、列表)
核心:超链接:HTML 最革命性的特点是“超文本”,即包含超链接的文本。点击超链接可以跳转到另一个文档或资源,正是这些链接将全世界的网页编织成一张“网”。
④三者关系:URL 告诉你资源在哪里(地址),HTTP 告诉你如何获取它(交通规则),而 HTML 则是你获取到的资源本身的内容和结构,并且里面包含了更多的 URL(超链接),让你可以继续浏览。
3.工作方式(https://www.google.com)
①URL 解析:浏览器解析你输入的 URL
②DNS 查询:浏览器向 DNS 服务器查询 www.google.com对应的真实 IP 地址(如 142.251.42.206)
③建立 TCP 连接:浏览器与服务器的 IP 地址建立 TCP 连接(通常是 80 端口用于 HTTP,或 443 端口用于 HTTPS)。
④发送 HTTP 请求:浏览器通过已建立的连接,向服务器发送一个 HTTP GET 请求,请求目标URL对应的资源。
⑤服务器处理并返回响应:服务器收到请求,找到对应的资源(如 HTML 文件),然后打包成一个 HTTP 响应报文发回给浏览器。状态码通常是 200 OK。
⑥浏览器渲染:浏览器接收到响应后,开始解析 HTML 文件
⑦关闭连接:页面加载完成后,TCP 连接可能会被关闭或保持以供后续请求使用
(二)http(报文结构:起始行、头部字段和消息体)
1.HTTPS 不是一个新的协议,而是 HTTP over SSL/TLS。它在 HTTP 和 TCP 层之间加入了一个 SSL/TLS 加密层。
2.请求报文(cli-->ser)
GET /index.html HTTP/1.1 // 请求行(定义要对资源执行的操作/要访问的资源路径/HTTP 版本)
Host: www.example.com // 头部字段开始
User-Agent: Mozilla/5.0...
Accept: text/html,application/xhtml+xml
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Connection: keep-alive //申请一次通信好多次
// 空行(分隔头部和主体,表示头部结束)
// 消息体(通常GET请求没有主体)
3.响应报文(cli<--ser)
HTTP/1.1 200 OK // 状态行(HTTP版本、状态码、原因短语)
Content-Type: text/html; charset=utf-8 // 头部字段开始
Content-Length: 1234
Server: Apache/2.4.41 (Ubuntu)
Set-Cookie: sessionId=abc123; path=/
Date: Mon, 23 Oct 2023 05:30:00 GMT
Connection: keep-alive
// 空行
<!DOCTYPE html> // 消息体开始
<html>
<head><title>Example Page</title></head>
<body>...</body>
</html>