计算机网络基本概念
在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。
计算机网络的分类与一般的事物分类方法一样,可以按事物所具有的不同性质特点分类。计算机网络通俗地讲就是由多台计算机通过传输介质和软件物理连接在一起组成的。总的来说计算机网络的组成基本上包括:计算机、网络操作系统、传输介质以及相应的应用软件四部分。
1.ip地址:互联网协议地址(英语:Internet Protocol Address,又译为网际协议地址),缩写为IP地址(IP Address)。IP地址是IP协议提供的一种统一的地址格式,它为互联网上的每一个网络和每一台主机分配一个逻辑地址,以此来屏蔽物理地址的差异。
ipv4:IPv4,是互联网协议(Internet Protocol,IP)的第四版,也是第一个被广泛使用,构成现今互联网技术的基础的协议。1981年 Jon Postel 在RFC791中定义了IP,Ipv4可以运行在各种各样的底层网络上,比如端对端的串行数据链路(PPP协议和SLIP协议) ,卫星链路等等。局域网中最常用的是以太网。IPv4使用32位(4字节)地址,因此地址空间中只有4,294,967,296(2)个地址。不过,一些地址是为特殊用途所保留的,如专用网络(约1800万个地址)和多播地址(约2.7亿个地址),这减少了可在互联网上路由的地址数量。随着地址不断被分配给最终用户,IPv4地址枯竭问题也在随之产生。基于分类网络、无类别域间路由和网络地址转换的地址结构重构显著地减少了地址枯竭的速度。但在2011年2月3日,在最后5个地址块被分配给5个区域互联网注册管理机构之后,IANA的主要地址池已经用尽。那么就意味着我们要使用下一代ip地址 ipv6
目前的全球因特网所采用的协议族是TCP/IP协议族。IP是TCP/IP协议族中网络层的协议,是TCP/IP协议族的核心协议。目前IP协议的版本号是4(简称为IPv4,v,version版本),它的下一个版本就是IPv6。IPv6正处在不断发展和完善的过程中,它在不久的将来将取代目前被广泛使用的IPv4。
ipv6:
IPv6是英文"Internet Protocol Version 6"(互联网协议第6版)的缩写,是互联网工程任务组(IETF)设计的用于替代IPv4的下一代IP协议,其地址数量号称可以为全世界的每一粒沙子编上一个地址 。
由于IPv4最大的问题在于网络地址资源不足,严重制约了互联网的应用和发展。IPv6的使用,不仅能解决网络地址资源数量的问题,而且也解决了多种接入设备连入互联网的障碍 。
互联网数字分配机构(IANA)在2016年已向国际互联网工程任务组(IETF)提出建议,要求新制定的国际互联网标准只支持IPv6,不再兼容IPv4。
2021年7月12日,中央网络安全和信息化委员会办公室、国家发展和改革委员会、工业和信息化部发布关于加快推进互联网协议第六版(IPv6)规模部署和应用工作的通知。
IPv6的地址长度为128位,是IPv4地址长度的4倍。于是IPv4点分十进制格式不再适用,采用十六进制表示。IPv6有3种表示方法。
一、冒分十六进制表示法
格式为X:X:X:X:X:X:X:X,其中每个X表示地址中的16b,以十六进制表示,例如:
ABCD:EF01:2345:6789:ABCD:EF01:2345:6789
这种表示法中,每个X的前导0是可以省略的,例如:
2001:0DB8:0000:0023:0008:0800:200C:417A→ 2001:DB8:0:23:8:800:200C:417A
二、0位压缩表示法
在某些情况下,一个IPv6地址中间可能包含很长的一段0,可以把连续的一段0压缩为"::"。但为保证地址解析的唯一性,地址中"::"只能出现一次,例如:
FF01:0:0:0:0:0:0:1101 → FF01::1101
0:0:0:0:0:0:0:1 → ::1
0:0:0:0:0:0:0:0 → ::
三、内嵌IPv4地址表示法
为了实现IPv4-IPv6互通,IPv4地址会嵌入IPv6地址中,此时地址常表示为:X:X:X:X:X:X:d.d.d.d,前96b采用冒分十六进制表示,而最后32b地址则使用IPv4的点分十进制表示,例如::192.168.0.1与::FFFF:192.168.0.1就是两个典型的例子,注意在前96b中,压缩0位的方法依旧适用 。
2.MAC地址:MAC(Media Access Control或者Medium Access Control)地址,意译为媒体访问控制,或称为物理地址、硬件地址,用来定义网络设备的位置。在OSI模型中,第三层网络层负责 IP地址,第二层数据链路层则负责 MAC地址。因此一个主机会有一个MAC地址,而每个网络位置会有一个专属于它的IP地址。
MAC地址是网卡决定的,是固定的。
这里可以看到 MAC地址是固定的 而ip地址是不固定的 因此可以用ip地址唯一标识一台主机
就例如把人看作一台主机 那么mac就是指的你这个人不管走到哪里都不会改变 而ip地址就如同位置一样 你在北京就会显示北京 你在西安就会显示西安 那么我们想找到你这个人 首先就是要获取你的ip地址
3.互联网:
4.端口号:
在网络技术中,端口(Port)包括逻辑端口和物理端口两种类型。物理端口指的是物理存在的端口,如ADSL Modem、集线器、交换机、路由器上用 于连接其他网络设备的接口,如RJ-45端口、SC端口等等。逻辑端口是指逻辑意义上用于区分服务的端口,如TCP/IP协议中的服务端口,端口号的范围从0到65535,比如用于浏览网页服务的80端口,用于FTP服务的21端口等。由于物理端口和逻辑端口数量较多,为了对端口进行区分,将每个端口进行了编号,这就是端口号。
如果把ip地址比作班级 那么端口号就可以比作班级里每一个学生的学号
计算机网络通讯
TCP/IP模型
计算机网络想要达到的目的就和进程间通信一样 想要完成两个不同客户端之间进程的数据传输
那么为什么要分层呢
我们可以用炒土豆丝来类比
如果在传输数据时出现了问题 我们就可以根据问题来找到是哪一个层面出现问题
例如我的QQ和其他人的QQ来进行通信
那么在 TCP/IP模型中的每一层的封装就如同上图所示
套接字
TCP用主机的IP地址加上主机上的端口号作为TCP连接的端点,这种端点就叫做套接字(socket)或插口。套接字用(IP地址:端口号)表示。它是网络通信过程中端点的抽象表示,包含进行网络通信必需的五种信息:连接使用的协议,本地主机的IP地址,本地进程的协议端口,远地主机的IP地址,远地进程的协议端口。
之前在进程间通信时我们提到了套接字 讲到套接字是全双工的
就意味着我们可以通过操作套接字来实现两个客户端上的通信
我们可以通过查看本机的ip地址来进行客户端通信
在 Windows和 Linux上查看本机ip地址的方式是不同的
在Windows上是在控制台输入以上代码
在Linux中是 ifconfig命令
然后我们就可以操作套接字进行通信
这里我们先给出服务端和客户端的代码
详细关于此类函数我们下一节再做了解
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main()
{
int sockfd = socket(AF_INET,SOCK_STREAM,0);//创建套接字
if ( sockfd == -1 )
{
exit(0);
}
struct sockaddr_in saddr, caddr;
memset(&saddr,0,sizeof(saddr));
saddr.sin_family = AF_INET;//地址族
saddr.sin_port = htons(6000);//端口号
saddr.sin_addr.s_addr = inet_addr("127.0.0.1"); //
int res = bind(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));//指定套接字的 地址(ip port)
if ( res == -1 )
{
printf("bind err\n");
exit(0);
}
listen(sockfd,5);//设置监听队列大小
while( 1 )
{
int len = sizeof(caddr);//caddr客户端的地址
int c = accept(sockfd,(struct sockaddr*)&caddr,&len);
if ( c < 0 )
{
continue;
}
printf("accept c=%d\n",c);
char buff[128] = {0};
int n = recv(c,buff,127,0);//read 接收数据
printf("buff=%s\n",buff);
send(c,"ok",2,0);
close(c);
}
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main()
{
int sockfd = socket(AF_INET,SOCK_STREAM,0);
if ( sockfd == -1 )
{
exit(0);
}
struct sockaddr_in saddr;
memset(&saddr,0,sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_port = htons(6000);
saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
int res = connect(sockfd,(struct sockaddr*)&saddr,sizeof(saddr));
if ( res == -1 )
{
printf("connect err\n");
exit(0);
}
char buff[128] = {0};
fgets(buff,128,stdin);
send(sockfd,buff,strlen(buff),0);
memset(buff,0,128);
recv(sockfd,buff,127,0);//
printf("buff=%s\n",buff);
close(sockfd);
exit(0);
}