1.网络技术
1.1网络体系结构
定义:指网络的分层模型和每层所使用的协议的集合
有两种体系结构:OSI和TCP/IP
1.1.1OSI
OSI模型把网络设备分成了7层:
1.应用层,FTP(文件传输),telnet(远程登陆)
2.表示层:数据格式定义、数据转换/加密
3.会话层:建立通信进程的逻辑名字与物理名字之间的联系
4.传输层:差错处理/恢复,流量控制,提供可靠的数据传送
5.网络层:数据分组、路由选择
6.数据链路层:数据组可发送、接收的帧
7.物理层:传输物理信号,接口信号形式、速率
----------理想化的模型
1.1.2TCP/IP四层模型:
----------实际使用
对于以上两种模型来说,除了物理层没有协议,其他层都有对应的协议去完成该层相应的功能
1.2.ip地址
1.2.1定义
IP地址:在网络中唯一标识一台主机的符号。
MAC地址(硬件地址):唯一标识一台主机的符号。
cmd 中 查看自己ip地址:ipconfig linux下:ifconifg。
一台主机的物理地址是固定的,而ip地址是不固定的,ip分配的。
1.2.2ipv4
现在使用的ip地址是ipv4 协议维护的地址
ipv4维护的ip地址宽度是四个字节
4个字节的ip地址可表示的地址范围是:
0000 0000*4-1111 1111*4
可以分成5类:
A 类: 1.0.0.1-126.255.255.254 机构占用。
B 类: 127.0.0.1-191.255.255.254 机构占用。
C类:192.0.0.1-223.255.255.254 用户ip地址 。
D类:224.0.0.1-239.255.255.254 组播&多播地址。
E类:240以后。
c类=24bit网络号+8bit主机号。
理论能接2^8=256台主机 实际上能接253台 256或者0或者1不能用。
子网掩码:255.255.255.0。
作用:相与判断是内网还是外网。
1.2.3网络协议
1.定义:通信双方对某种通信规则的约定。
2..协议:
(1)通用的网络协议 TCP/IP协议栈(封装在os)
(2)行业内部专用的网络协议 协议开发
(3)用户自定义协议 产品
3.常用协议
1.2.4端口号
- 作用:用端口号区分应用进程
- 端口号是一个无符号的整数,范围1-65535
(1)1-1023 众所周知端口号,已经被占用
(2) 自定义从1024开始到65535
1.2.5字节序
1.2.5.1主机字节序
(1)不同的cpu主机存储多字节的整数方式,有大端序和小端序
大端序主机:数据的高字节存放在内存的低地址
小端序主机:数据的高字节存放在内存的高地址
主机字节序转化为网络字节序
htonl
htons
(2)多字节整数发送前要从主机字节序转化成网络字节序,以适配对端的网络主机
1.2.5.2网络字节序
网络字节序:大端序
2.基于TCP协议的网络客户端和服务器模型
三次握手以及四次挥手
2.1服务端
五个步骤:
socket--->bind---->listen---->accept---->IO函数
2.1.1socket 创建套接字
socket作用:创建一个用于通信的网络软通道
int socket(int domain,int type,int protoco)
参数:1.地址族
2.套接字类型
SOCK_STREAM流式套接字
SOCK_DGRAM 数据报套接字
3.通常为0:自动匹配其他类型的协议
返回值:正确返回文件描述符 为3(因为系统已经自动打开了3个文件描述符,标准输入,标准输出,错误信息)文件描述符3(用于连接客户端),错误返回-1,
2.1.2bind 绑定主机的地址和端口
struct sockaddr_in stserver;
stserver.sin_family=AF_INIT;
stserver.sin_port=honts(8888);
stserver.sin_addr.s_addr=inet_addr(“127.0.0.1”);
inet_addr();数值转换为32位无符号
0.0.0.0 万能地址
int bind(int sockfd,struct sockaddr*addr,int addrLen)
参数:1.套接字的返回值
2.指向定义好的目标信息结构体
3.第二个参数的长度
返回值:成功返回0,失败-1
2.1.3listen 设置监听套接字
listen(int sockfd,int backlog);
参数:1.文件描述符(监听连接的套接字)
2.最多能侦听多少个服务端
返回值:成功返回0,失败-1
2.1.4 accept 接受TCP连接
int accept(int sockfd,struct sockaddr*addr,socklen_t*addrlen)
参数 1:监听的套接字
2. .用来存放对方的地址信息
3..地址长度的信息
返回值:成功返回新的文件描述符(新的网络软通道)用于下一步收发数据,失败-1
2.1.5recv/send 收发数据
ssize_t recv()
函数参数:
1.客户端接收的文件描述符(新的)
2.准备好的数据
3.接收大小
4.阻塞0非阻塞1
函数返回值:已经接收到的字节个数,失败-1
send
函数参数:
- 文件描述符
- 提前准备好的数据
- 大小
- 阻塞0或非阻塞1
函数返回值:成功返回成功发送的字节个数,失败-1
注意!
2.2客户端
socket---->connect----->IO函数
2.2.1socket 创建套接字
int socket(int domain,int type,int protoco)
参数:1.协议域
2.套接字类型
SOCK_STREAM流式套接字
SOCK_DGRAM 数据报套接字
3.通常为0:自动匹配其他类型的协议
返回值:正确返回,错误返回-1,
2.2.2 connect 建立连接
函数参数:
1.文件描述符(socket的返回值)
2.服务端的地址信息
3.结构体的大小
函数返回值:成功返回0,失败-1
2.2.3 send/recv
客户端只有一个通道,服务端两个
send
函数参数:
1.文件描述符
2.提前准备好的数据
3.大小
4.阻塞0或非阻塞1
函数返回值:成功返回成功发送的字节个数,失败-1
ssize_t recv()
函数参数:
1.客户端接收的文件描述符(新的)
2.准备好的数据
3.接受大小
4.阻塞0非阻塞1
函数返回值:已经接收到的字节个数,失败-1
注意:测一次的话最后关闭
2.2.4 所有系统头文件
linux下的头文件在:/usr/include
3.基于UDP协议的客户端和服务器模型
3.1服务端
socket------>bind------>IO函数(recvfrom/sendto)
3.1.1 socket 创建套接字
允许端口重用
3.1.2 bind 绑定主机地址和端口号
3.1.3 recvfrom/sendto 收发
函数参数:
5.对方的地址信息,6.地址长度
函数参数:
5.对方的地址信息 6.长度sizeof
3.2 客户端
socket----->IO函数(recvfrom/sendto)
3.2.1 socket 创建套接字
3.2.2 recvfrom/sendto 收发
4.两种网络编程框架的对比
4.1.TCP:使用了流式套接字(SOCK_STREAM)
4.1.1定义
提供一个面向连接、可靠的数据传输服务,数据无差错、无重复的发送且按照发送顺序接收。内部设置了流量控制,避免数据流淹没满的接收方。数据被看作是字节流,无长度限制。
4.1.2 协议
TCP(传输控制协议):
TCP 是一个可靠的,全双工的,有序的,面向链接的字节流通信的协议。
为什么可靠:
1.丢失的数据包重发(能保证拿到数据)
2.错误的数据包重发 (保证能拿到正确的数据)
3.数据的有序到达(因为对每个数据包进行了编号)(拆包,编号)
4.有较为健全的校验机制(为了保证数据的正确性)
5.支持面向连接(保证通信线路的畅通)-->三次握手
6.有信道拥堵控制(通过一种对于信道拥堵解决的方案,来提产生的原因,是中继设备中(接收的速度 >> 发高转发效率)送的速度)
为什么有序(有序列号):
1.保证数据都能传输给对端,不至于当传输的数据>信道
带宽,导致数据丢弃。
2.通过序号,在对端主机上可以拼接成原本的数据包
3.保证数据传输的可靠性
4.2.UDP:使用了数据报套接字(SOCK_DGRAM)
4.2.1 定义
提供了无连接服务。数据包以独立数据包的形式被发送,不提供无差错保证,数据可能丢失或者重复,顺序发送,可能会乱序接收。
4.2.2 协议
UDP(The User Datagram Protocol):无连接的数据报协议,别名"不可靠的协议"
<1>使用校验和来实现错误侦测
<2>UDP常用于媒体流的传输(音频、视频、等), 在这种情况
下,实时性比
可靠性更重要
<3>UDP也常用于简单的查询/回应程序,例如DNS查找,在
这种情况下,建立可靠传输的资源消耗太大
<4>UDP是一种实时传输协议(Real-time Transport Protocol),这
种协议通常用来传输实时数据例如:音视频流
不可靠的原因:
1.非面向连接(不关心接收端是否在线-)--》没有三次握手
2.丢包不重发
3.错误的包不重发
4.3如何抉择使用 TCP 还是 UDP?
1.可靠性
2.实时性
可靠性 > 实时性:TCP
可靠性 < 实时性: UDP
4.4原始套接字(SOCK_RAM)--ping.c
可以对较低层次协议如IP,ICMP直接访问。
5. IO模型
5.1在UNIX/linux下主要有4种I/O模型:
5.1.1阻塞I/O:
send/recv sendto/recvfrom 最常用、最简单、效率最低
5.1.2.非阻塞I/O:
可防止可防止进程阻塞在I/O操作上,需要轮询
5.1.3 I/O 多路复用:
允许同时对多个I/O进行控制
5.1.4.信号驱动(异步)I/O:
一种异步通信模型
5.2常见的阻塞I/O函数
recv,send;ercvfrom,sendto;read,write;accept,connect。
5.3非阻塞IO函数
非阻塞的标志 :O_NONBLOCK
常见的非阻塞IO函数:read/write(可以通过修改底层驱动设计成非阻塞)
5.4IO多路复用
5.4.1基本思想
1.先构造一张有关描述符的表,然后调用一个函数。当这些文件描述符中的一个或多个已准备好进行IO时函数才返回。
2.函数返回时告诉进程那个描述符已就绪,可以进行I/O操作。
5.4.2步骤
- 构建一张文件描述符集合表,表的大小为1024bit,这些bit位分别对应了1024个文件描述符,这些bit位中存放的数据表示的是该描述符对应的IO通道是否有数据发生,1表示有数据,0表示没有数据
- 调用一个监测函数select ()监测程序的文件描述符对应的通道是否有数据发生?如果有数据发生,将文件的描述文件符集合表的相应bit位置1,同时将其他位置的bit位置0,并返回监测到的文件描述符的通道个数。
函数:int select(int n, fd_set *read_fds, fd_set *write_fds, fd_set *except_fds, struct timeval *timeout);
作用:监控文件描述符对应的IO通道是否有数据
参数:1. n :最多监控的个数
2.读文件描述符的集合表,也就是前面创建的
3.指向写文件描述符的集合表
4.指向异常文件描述符集合表
5.为0时,只检测文件描述符集合的状态。然后立即返回
为NULL时,函数阻塞监控关注的文件描述符通道
为 一个时间时,时间到达之前select函数一直阻塞,时间到才结束监控
返回值:监控到的有数据发生的IO通道的个数,失败-1
5.4.3 对检测的结果做出判断和响应
循环遍历文件描述符集合表中,查看集合表中关心的描述符对应的bit位是否是1,如果为1,响应这路IO,如果是0,继续循环。
int (FD_ISSET(0,stFdr))
{响应0对应的通道数据 fgets();
5.4.4 atoi函数和snprintf函数
6.服务器模型
6.1常用的服务器模型
6.1.1服务器定义
可以服务于多个客户端的服务程序 。
6.1.2种类
循环服务器:指的是该服务程序可以服务多个客户端,但同一个时刻只能响应一个客户端。
并发服务器:指的是该服务器可以在同一时刻服务于多个客户端。
在linux系统中,实现并发服务器地址,可以使用:多进程 多线程 select poll epoll。
6.1.3多进程
思想:主进程专门用于连接多个客户端,若有一个客户端进来,就创建一个子进程来负责该客户的业务数据的收发。
缺点:每一个进程都需要一个4g虚拟空间,系统开销大。
6.1.4 多线程
思想:主进程专门用于连接多个客户端,若有一个客户端接进来,就创建一个子线程来负责该客户端的业务数据的收发。
6.1.5.select--->IO多路复用
思想:
1 .构建一张文件描述符集合表,表的大小为 1024bit,这 1024 个 bit 位用来存放 1024 个文件描述符对应的 IO 通道是否有数据发生,有数据发生的通道对应的 BIT 位置 1,没数据发生的通道对应的bit位置 0--->空表.
2.使用 select 函数去监控关注的文件描述符对应的通道是否有数据发生,若监控到一路或多路通道有数据发生,则返回通道的路数同时将有数据发生的通道对应的文件描述符的集合表的相应bit为置1,同时将其他的bit位置0;
3.对文件描述符集合表中的置位结果做出判断和响应。使用 FD ISSET 去判断关心的描述符是否被置位了,若被置位了,返回真,那么响应这路 IO:若没有被置位,返回假,不做处理
7.网络服务器超时检测
7.1 select 超时设置
int select(int n, fd_set *read_fds, fd_set *write_fds, fd_set *except_fds, struct timeval *timeout);
最后一个参数:
timeout:超时时间,若在指定的时间内没有客户端连接该服务器服务器会一直阻塞,当指定时间到时,没有客户端连接,select阻塞时间到,返回 0
7.2 使用信号和alarm
signal(1.信号,2信号对应的新的处理函数)
sigactin()
作用:既可以set,又可以get
SA_RESTART 重启 ~SA_RESTART不重启
sigaction(信号,NULL,&act);获取信号对应的旧的处理函数
sigaction (信号,&act,NULL);安装新的信号
取反表示不重启
7.3可以设置socket套接字属性
setsockopt(sockfd,)
作用:
1.设置的套接字描述符
2.这个层面的属性
3.超时时间
4.tv大小
7.4端口重用
加在socket之后
int setsockopt(int sockfd,int level,int optname,const void*optval,socklen t *optlen)
功能:设置属性
8.广播,组播
在网络中,数据包的发送方式有三种:单播 广播 组播
1.广播:数据发送方将数据包发送给了局域网中的所有的主机。
8.1广播
广播发送: socket-->创建数据报型的套接字setsockopt--->设置属性(允许广播发送)--->sendto
发送(广地址)改为192.168.12.255(当前的广播地址) 255.255.255.255(万能地址)
广播接收:socket---> (创建数据报套接字) bind--->(绑定端口号和ip)revfrom
8.2组播
组播: 数据发送方将数据包发送到了某个主机的组播组里,加入到该组播组的所有的主机能够接收到组播数据组播地址: 224.0.0.1~239.255.255.254 (D类地址)
发送:sock ----> 指定组播地址------>sendto
接收:sock----> 加入组播组-------->bind---->recvfrom
struct ip_mreq 定义一个对象 mreq--->组播地址
和 IP地址。定义好之后初始化。
setsockopt();
注意:数据包的发送方式:单播(一对一),广播(一对多),组播(多对多)
9.unix域套接字
本质:socket文件
Unix域套接字有两种:
流式套接字 和数据包套接字
9.1TCP流式套接字
使用 TCP 协议的网络编程框架创建流式套接字文件,该套接字文件可以实现一台主机上两个本地进程的通信
服务端5步: socket-->bind(生成一个文件名用来标识socket文件)-->listen-(监听有没有发消息)->accept-->IO(可以是read write 或者 recv send)
函数客户端: socket-->connect-->IO 函数
9.2UDP数据报套接字
使用 UDP 协议的网络编程框架创建数据报套接字文件,该套接字文件可以实现一台主机上两个本地进程的通信。
发送方: socket-->bind-->I0 函数
接收方: socket-->bind-->IO 函数
注意: udp 方式 unix 域套接字,类似于有名管道,实现双工通信需要两个管道文件。用于两个不相关进程的通信。
9.2.1发送端
1.socket
2.send
3.recvfrom bind
4.sendto/recvfrom
9.2.2收端
1.socket
2.bind
3.sendro/ercvfrom
linux一共有7种文件
b 块设备文件 c:字符设备 d -l s p