计网 七层网络模型

计网 七层网络模型

一.协议(protocol)

1.什么是协议

数据在网络中传输时按照的规则就是协议(protocol)

协议(protocol)规定了数据在网络中传输的顺序,格式,以及携带哪些内容

二.IOS/OSI开放式系统互联理论模型(也叫七层网络模型)

拓展:IOS/OSI开放式系统互联理论模型是一个完整的系统(系统:有自己完整的功能,并且能进行二次开发的)

1.IOS/OSI开放式系统互联理论模型的组成

(1)应用层
1.功能

应用层是运行一些应用程序(qq,微信等)

2.应用层用到的协议
1>HTTP(端口号为80):访问网站需要的协议
2>HTTPS(端口号为443):访问网站需要的协议(HTTPS比HTTP多了一个SSL加密方式,所以HTTPS更安全)

如下图访问百度网站用到了HTTPS协议

在这里插入图片描述

注意:www.baidu.com叫做域名(domain name)

3>FTP(端口号为21):文件传输协议
4>DNS(端口号为53):域名解析协议(把好记的域名转为IP地址)
5>DHCP(端口号为68):自动获取网络配置的协议
6>Telnet(端口号为23)
7>Smtp(端口号为25)
8>SSH(端口号为22)
(2)表示层
1.功能

1.数据加解密:发送之前加密,接收到之后解密

2.数据解压缩:将一个数据在发送前进行压缩,其总的数据量变小,传输的就快,占用网络通道时间就更短(网络通道是大家共用的),接收到之后解压缩。

3.图片/视频编解码:在发送之前将图片和视频进行编码,在接收到之后解码

(3)会话层
1.功能

1.session会话管理:登录一个网站后,例如爱奇艺,当登陆完账户之后,再在爱奇艺中打开其他页面就不需要再次重新登录了,因为是同一个账户(也叫做同一个会话),保证用户信息不会过期不需要登录

2.服务器验证用户登录:当访问某一个网站/服务器,要做用户登录,输入用户名和密码,验证密码是否正确,用户是否存在

3.断点续传:在下载一个应用的时候,断网了,恢复网络的时候,还是从没下的部分进行下载,下过的部分进不需要再下载了

(4)传输层
1.传输层用到的协议
1> TCP

TCP是传输控制协议,提供一种面向连接的、可靠的、基于字节流的传输层通信协议,有流量控制和差错控制,使用TCP协议的应用有邮件的接收和发送、文件传输、远程登录等。

需要数据稳定和完整性比较高的场景多使用TCP协议

2> UDP

UDP是用户数据报协议,提供一种无连接的、高效率的、低可靠性的数据传输服务,使用UDP协议的应用比如音视频聊天、在线游戏王者荣耀、工业物联网数据传输等。

需要数据时效性比较高的场景多使用UDP协议

3> 线程
4> 端口

端口决定了在数据到达设备后,操作系统要把这个数据分配到具体哪一个应用程序(应用程序会绑定端口号)

注意:应用程序和端口号之间的关系是一对多的关系,一个应用程序可以绑定多个端口号,一个端口只能被一个应用程序所绑定(一旦端口被绑定了,那其他应用程序就不能绑定该端口)

5> socket(套接字)

socket是通信的基石,是支持TCP/IP协议的网络通信的基本操作单元,包含进行网络通信必须的五种信息:连接使用的协议、本地主机的IP地址,本地进程的协议端口,远地主机的IP地址,远地进程的协议端口

(5)网络层
1.网络层用到的设备
1>防火墙

保护电脑安全,有两种方式

1.黑名单:通过拉黑IP地址,所有端口都不会接受拉黑IP地址发出的数据,以保护电脑安全

2.白名单:设备/某些应用程序只允许某些端口被外部访问,以保护电脑安全

2>路由器
2.网络层用到的协议
1>IP

IP是每一个接入网络设备都要具有的

查看IP的步骤

1.windows键+R键,打开一个窗口,如下

计网 七层网络模型_第1张图片

2.输入cmd,确定,就会出现命令输入窗口

计网 七层网络模型_第2张图片

计网 七层网络模型_第3张图片

3.在命令输入窗口中输入ipconfig(ip的相关配置)

计网 七层网络模型_第4张图片

4.就可以看到当前当前电脑ip地址的相关配置了

计网 七层网络模型_第5张图片

IP地址分为两类,一种是IPv4地址,另一种是IPv6地址

2>ARP
3>RARP
(6)数据链路层
1.数据链路层用到的设备
1>网卡

当我们使用网卡的时候就会给网卡分配一个IP地址(手动分配或者是自动获取的)

网卡除了IP地址还有MAC地址,MAC地址出厂的时候是全球唯一的(生产网卡的厂商会给它分配全球唯一的MAC地址)

2>交换机

交换机与路由器的区别:

1.交换机只能通过单纯的物理连接

2.交换机的数据不能跨交换机,路由器可以跨路由器

(7)物理层
1.功能

将设备中传输的数字信号转换成电信号或者是光信号,通过光缆或者是电缆传输到对端去

2.看下面图片进行加深理解

计网 七层网络模型_第6张图片

3.基于七层网络模型的数据传输的过程

发射端应用层->发射端表示层->发射端会话层->发射端传输层->发射端网络层->发射端数据链路层->发射端物理层,然后转换成电信号或者是光信号通过电缆或者光缆传输到对端设备,再从对端设备的物理层->对端设备的数据链路层->对端设备的网络层->对端设备的传输层->对端设备的会话层->对端设备的表示层->对端设备的应用层

三.TCP/IP事实标准网络模型

1.TCP/IP事实标准网络模型的组成

(1)应用层

(2)传输层

(3)网络层

(4)物理层

四.C/S(Client/Server)模型与B/S(Browser/Server)模型

1.C/S模型的特点

1.访问应用程序的客户端固定(每一个应用程序都有自己固定的客户端,只能由自己固定的客户端访问)

2.客户端和服务端的协议可以是任意协议(常用的是TCP和UDP协议)

2.B/S模型的特点

1.访问网站的浏览器不固定(一个网站可以由多个浏览器访问)

2.必须使用HTTP或者是HTTPS协议

3.写一个C/S模型的数据通信(客户端和服务端的协议用的是UDP协议)

1.看下图,理解C/S模型的数据通信的过程

计网 七层网络模型_第7张图片

2.C/S模型的数据通信的过程

1.加载库(库为ws2_32.lib)

2.创建套接字(所用到的函数为socket())

3.绑定IP地址和端口号

4.接消息(所用到的函数为recvfrom()),回消息(所用到的函数为sendto())

5.关闭套接字(所用到的函数为closesocket()),卸载库(所用到的函数为WSACleanup())

3.使用代码实现C/S模型的数据通信
1.创建一个新项目(选的是空项目)

计网 七层网络模型_第8张图片

2在该项目下创建一个文件,在该文件中进行代码的实现如下
#include
#include
//这里说一下包含头文件时的一个知识点
//<>就是在操作系统指定的地方开始找要包含的头文件
//“”就是从当前文件夹开始找要包含的头文件
using namespace std;

//导入依赖库(使用WSAStartup函数和WSACleanup函数时需要此依赖库)
#pragma comment(lib,"Ws2_32.lib")//这里只需要输入名字就行,编译器知道它的具体路径在哪

int main() {


	//1.加载库

	//创建一个WORD类型的变量
	WORD version = MAKEWORD(2,2);//MAKEWORD这个宏是创键一个WORD类型的变量(这里创建的是2.2版本的WORD类型的变量,然后用version接一下这个变量的值)

	//定义一个结构体变量
	WSADATA data;

	//加载库的函数
	int err = WSAStartup(version, &data);/*此函数的头文件为winsock2.h,此函数第一个参数是一个输入参数,该输入参数一个是版本号(WORD类型的)
										 第二个参数是输出参数,该输出参数是一个结构体指针
										 接一下返回值,并根据返回值判断是否成功*/
										 
	//判断是否成功,打印日志
	if (err != 0) {
		cout << "WSAStartup error" << endl;
		return 1;
	}

	//判断加载的版本号是否正确
	if (LOBYTE(data.wVersion) != 2 || HIBYTE(data.wVersion) != 2) {
		cout << "WSAStartup Version error" << endl;
		//卸载库(程序退出之前需要将加载的库卸载)
		WSACleanup();//此函数没有参数
		//程序退出
		return 1;
	}
	else {
		cout << "WSAStartup suuccess" << endl;
	}


	//2.创建套接字
	SOCKET sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);/*此函数的第一个参数是使用的地址族格式(我们这里填的是AF_INET(这是个宏定义),表示用的使用IP地址的格式是IPv4类型的),
															 第二个参数是表示创建一个什么类型的套接字,这里填的是SOCK_DGRAM(这个是宏定义)表示创建的是使用UDP的套接字
														     第三个参数表示用哪个协议,这里填的是IPPROTO_UDP(这个是宏定义)表示使用的是UDP的协议
															 如果此函数成功了,那么此函数返回的是新创建出来的套接字
															 如果失败了,返回的是INVALID_SOCKET*/
	//判断套接字是否创建成功
	if (sock == INVALID_SOCKET) {
		cout << "socket error" << endl;
		//获取失败的错误码并进行打印输出
		cout << WSAGetLastError() << endl;
		//卸载库(程序退出之前需要将加载的库卸载)
		WSACleanup();//此函数没有参数
		//程序退出
		return 1;
	}
	else {
		cout << "socket success" << endl;
	}

	//3.绑定ip地址和端口号(在操作系统那注册一下当前进程对应的ip和端口)
	
	//定义一个sockaddr_in类型的结构体
	sockaddr_in addServer;
	//进行结构体的初始化
	addServer.sin_family = AF_INET;//初始化地址族格式,和上面套接字的地址族格式一样,表示用的使用IP地址的格式是IPv4类型的
	addServer.sin_port = htons(666666);//绑定端口号(端口号可以随便写,但是为了避免和已有的应用程序绑定的端口号重复,端口号最好写5位或6位的长度的),htons函数是将端口号的存储方式转换成网络字节序(大端存储)
	addServer.sin_addr.S_un.S_addr = INADDR_ANY;//绑定所有网卡(因为大部分设备不只有一个网卡(也就不只有一个IP地址))
	//绑定IP地址和端口号的函数
	err = bind(sock, (sockaddr*)&addServer,sizeof(addServer));/*此函数的第一个参数是套接字
					第二个参数是sockaddr类型的结构体指针
					第三个参数是第二个参数中结构体所占的空间的大小
					如果此函数成功了,
					如果失败了,*/
	if (err== SOCKET_ERROR) {
		cout << "bind error" << endl;
		//获取失败的错误码并进行打印输出
		cout << WSAGetLastError() << endl;
		//关闭套接字,卸载库
		closesocket(sock);//在将加载的库卸载之前关闭套接字
		WSACleanup(); //程序退出之前需要将加载的库卸载

		//程序退出
		return 1;
	}
	else {
		cout << "bind success" << endl;
	}
    
	int recv = 0;//定义一个变量用来接recvfrom函数的返回值
	int send = 0;//定义一个变量用来接sendto函数的返回值
	char recvData[1024] = ""; //定义一个空间用来接要来的数据
	char sendData[1024] = "";//定义一个空间用来接要来的数据
	sockaddr_in recvaddr;//定义一个sockaddr_in的结构体,这里要存的是数据是从哪个端口号和ip来的(这里注意要强转成sockaddr*)
	int recvaddrlength = sizeof(recvaddr);//这个变量存的是sockaddr_in结构体的空间大小
	while (true) {
	//4.接受数据
	recv=recvfrom(sock, recvData,sizeof(recvData),0, (sockaddr*)&recvaddr, &recvaddrlength);
     /*
    第一个参数是用哪个套接字接收数据(输入参数)
    第二个参数是用来接收数据的空间(输出参数)
    第三个参数是用来接收数据的空间的长度(输入参数)
    第四个参数是标志位,如果有特殊套接字的话要设置标志位,这里无特殊的,不需要使用标志位,填0(输入参数)
    第五个参数是一个sockaddr的结构体,这里存的是端口号和ip,表示数据是从哪个ip地址和端口号来的(输出参数)
    第六个参数是第五个参数结构体的大小(输入,输出参数)
    如果成功了,返回的是接收到的数据的字节数
    如果失败了返回SOCKET_ERROR 
    */
	if (recv > 0) {
         //打印ip地址和接收的数据
         cout << "IP:" << inet_ntoa(recvaddr.sin_addr)/*这里因为recvaddr.sin_addr这个变量村的ip地址是u_long类型的,看不懂,所以我们要转成字符串类型*/ << "     " << "SAY: " << recvData << endl;
         //我们打印出来能看懂的ip地址,"192.168.3.123"这个是十进制四等分ip字符串类型的地址
         //我们打印出来看不懂的ip地址,u_long类型的ip地址
         //这里介绍两个函数
         //inet_addr(),这个函数是将字符串类型转换成u_long类型
         //inet_ntoa(),这个函数是直接把sin_addr的结构体转换成字符串类型
     
	}
        
        
	//5.发送数据
    cin >> sendData;//把要输出的数据存到用来发送数据的空间
	send = sendto(sock, sendData, sizeof(sendData), 0, (sockaddr*)&recvaddr, recvaddrlength);
	/*第一个参数是用哪个套接字发送数据(输入参数)
    第二个参数是用来发送数据的空间(输出参数)
    第三个参数是用来发送数据的空间的长度(输入参数)
    第四个参数是标志位,如果有特殊套接字的话要设置标志位,这里无特殊的,不需要使用标志位,填0(输入参数)
    第五个参数是一个sockaddr的结构体,这里存的是端口号和ip,表示数据是发到哪个ip地址和端口号(输出参数)
    第六个参数是第五个参数结构体的大小(输入,输出参数)
    如果成功了,返回的是发送的数据的字节数
    如果失败了返回SOCKET_ERROR 
    */
	if (send == SOCKET_ERROR) {//如果失败了
			//输出错误日志,获取失败的错误码并进行打印输出
			cout << "send failed  " << WSAGetLastError() << endl;
			break;
		}
        
	//6.关闭套接字
	closesocket(sock);
	//7.卸载库
	WSACleanup();//此函数没有参数
	return 0;
}

你可能感兴趣的:(计算机网络,网络)