网络:
协议(七层,五层模型分别是什么,干什么的,对应哪些协议)
arp协议
IP协议(头部)
tcp协议(三次握手,拥塞控制,滑动窗口)
http协议(头,方法,状态码,请求过程)
网络编程:
基本api(功能,对应阶段,基本流程(客户端,服务器端))
讲一个简单的示例程序的流程(回射服务或者更复杂一点的程序)
I/O复用
信号,定时器
多进程多线程编程
调试(简单知道一点就行了)
OSI模型七层结构:
物理层,(比特流)设备之间比特流的传输,物理接口,电气特性
数据链路层,(帧)将数据分帧,用mac地址访问媒介
网络层,(包)实现点到点的数据通信
传输层,(段)不同机器上进程之间的数据通信
会话层,(数据)不同机器上的用户之间建立会话关系
表示层,(数据)数据的表现形式,如数据加密
应用层,(数据)用户接口
TCP/IP协议族:
五层模型多一个物理层
数据链路层,ARP RARP
网络层,IP ICMP
传输层,TCP UDP
应用层,PING HTTP FTP TELNET
常见协议的作用及底层协议:
ARP,实现IP到MAC地址的转换
RARP,实现MAC地址到IP地址的转换
ICMP,控制报文协议,在主机路由器之间传递控制信息,比如主机是否可达,网络通不通,路由是否可用
PING,检查网络是否连通,底层利用ICMP
HTTP,超文本传输协议,传输网页的,底层利用TCP,端口是80
FTP,文件传输协议,底层利用TCP,端口21
TELNET,远程登录,底层协议TCP,端口23
DNS,域名服务,基于UDP和TCP协议的,端口号53,用户到服务器采用UDP,DNS服务器通信采用TCP
ARP协议工作过程:主机A发送arp请求报文给本网络的所有主机,每个主机接到这个ARP请求报文之后就会拿自己的IP和这个包里的IP比对,如果不一样直接丢弃,如果一样,就把该包中包含的主机A的mac地址和IP地址加到自己的arp缓存表中,并把自己的mac地址填入arp响应报文中,在发送给主机A,主机A将查询的结果加到自己的arp缓存表中。(存在的安全问题:ARP欺骗,伪造mac地址和IP地址,截获本应发送给其他主机的信息,从而窃取机密或者造成其他主机的通信故障)
TCP协议:
三次握手四次挥手:https://www.cnblogs.com/thrillerz/p/6464203.html
三次握手:主机A向主机B发送syn报文,主机B接收到主机A的syn并向主机A发送syn报文+ack报文,主机A接收主机B发送的syn+ack报文并向主机B发送ack报文,主机B接收到主机A的ack报文三次握手完成。
主机A的状态变化:主机A向主机B发送syn报文,主机A处于syn-send状态,主机A接收主机B发送的syn+ack报文并向主机B发送ack报文,主机A进入establish状态
主机B的状态变化:主机B接收到主机A的syn并向主机A发送syn报文+ack报文,主机B由listen状态进入syn-recieve状态,主机B接收到主机A的ack报文,主机B进入establish状态。
四次挥手:主机A向主机B发送fin报文(主机A进入fin-wait1状态),主机B向主机A发送ack报文(主机A接收到Ack进入fin-wait2状态),主机B向主机A发送fin报文,主机A向主机B发送ack报文
主机A的状态变化:主机A向主机B发送fin报文,主机A进入fin-wait1状态,主机A接收到Ack进入fin-wait2状态,主机A发送ack报文进入time-wait状态,等待2MSL(报文段最大生存时间)的时间进入close状态
主机B的状态变化:主机B接收到主机A的fin报文并向主机A发送ack报文,进入close-wait状态,主机B向主机A发送fin报文,主机B进入last-ack状态,主机B接收到主机A的ack报文进入close状态
为什么需要time-wait状态:可靠的中止tcp连接,如果最后的ack报文丢失,可以重新接受fin和重新发送ack报文;让迟来的tcp报文有足够的时间被识别和丢弃,如果不存在time-wait状态,一个新的连接立即被打开,就有可能接收到原来旧连接的报文,这是错误的。存在time-wait状态可以保障两个方向上的迟到的报文都消失。
拥塞控制:四个部分慢启动、拥塞避免、快速重传、快速恢复
拥塞控制主要是控制拥塞窗口的大小(CWND,以字节为单位的)
慢启动阶段:cwnd被设置为2-4个mss,每次增加之前未被确认的字节数(第一次发2,第二次就发2+2=4,第三次就发4+4=8)因此呈指数增长
拥塞避免:慢启动增长速度很快,为了避免发生拥塞,需要降低其增长速度。设定一个门限值,如果cwnd大于这个门限值,那么进入拥塞避免阶段,cwnd每次增加一个mss,呈线性增长
慢启动和拥塞避免阶段都有可能发生拥塞,拥塞的检测方法是:一超时,二收到重复的确认报文
对于第一种的解决方法是重新进入慢启动和拥塞避免,即调整门限值为当前未收到确认的字节数的一半(但是不低于2个mss),调整cwnd小于mss
对于第二种情况需要进行快速重传和快速恢复,快速重传,当收到三个重复的确认报文的时候,将门限值设置为当前未收到确认的字节数的一半(但是不低于2个mss),将cwnd调整为门限值+3个mss.然后进入拥塞避免(即每次加一个mss)
快速恢复,当收到新的确认报文的时候,将cwnd调整为门限值,将cwnd每次增加一个mss(即进入拥塞避免阶段)
滑动窗口:就发送端而言分四个部分:已经被接受的部分(发送并收到确认的);已经发送但是未被确认的;允许被发送的;不允许被发送的;其中二三合起来就组成了发送窗口
http协议:
这篇总结的相当好:https://www.cnblogs.com/sunny-sl/p/6529830.html
http://www.cnblogs.com/jackson0714/p/HTTP1.html
请求报文格式:请求行(方法,uri, 版本),请求头部,请求内容
响应报文格式:状态行(版本,状态码,状态码描述),响应头部,响应内容
基本方法:
get:请求uri(统一资源标识)标识的资源(因为利用url传参,所以不安全)
post:向服务器传递信息
put:向服务器传输文件
delete:从服务器删除文件
head:与get相同,但是只返回资源的头部,用于验证资源
opotion:查询资源支持的http方法
状态码:
1**,指示信息,表示已接受,继续处理
2**,成功,请求已被成功接收
3**,重定向,需要进行其他的操作
4**,客户端错误(400语法错误,401需要认证,403资源禁止访问,404资源不存在)
5**,服务器端错误(500服务器内部错误,503服务器忙)
http和https的区别:https=http+加密+认证+内容完整性保护
https是如何实现的?
在http的基础上,首先加了一个认证的过程,运用非对称加密交换对称加密的密匙(用公钥进行加密,是为了说明这个消息是发送给谁的,用私钥进行加密是为了说民跟这个小时是我发送的,所以a要告诉b对称加密的密钥就用b的公钥进行加密),然后每次传输的内容就可以用对称加密进行加密了(对称加密效率高,因此不用非对称加密),接受到的内容有可能被截取或者修改导致不完整,因此最后再尽心给一个完整性验证(每次发送消息的时候同时发送对消息进行哈希得到的哈希值,接收方收到消息之后只需要再做一次哈希然后和给定的哈希值进行比对就知道消息是否是完整的了)
请求过程:
https://www.cnblogs.com/YeChing/p/6337378.html
域名解析(需要先查找域名服务器的ip地址,然后向域名服务器发送请求,域名向ip地址的转换)
浏览器向服务器的80端口发起tcp连接(三次握手)
浏览器发起http请求,服务器响应,传递给客户端html代码
客户端解析html代码,再向服务器请求其中的图片等资源,服务器响应
数据的传输涉及到封装和分用
浏览器对页面进行渲染呈现给用户
http1.0,http1.1和HTTP2.0的区别
https://blog.csdn.net/linsongbin1/article/details/54980801/
http1.0 http1.1
http1.1默认支持长连接,http1.0需要使用keep-alive才能获得长连接
http1.1支持只传送请求头部,如果资源允许访问再发送请求内容,可以节约带宽
http1.1支持host域,支持虚拟站点,多个站点共享同一个ip和端口
http1.1 http2.0
http2.0支持多路复用,一个tcp连接可以并发处理多个请求,而http1.1要实现并发处理多个请求需要建立多个连接
http2.0支持压缩,对请求头部进行压缩节省带宽
http2.0支持服务器推送,服务器会把客户端可能需要的资源一次性返回给客户端,客户端进行缓存,加载的时候直接从本地进行加载
访问网页的过程:
网络编程:
基本api:
客户端和服务器端通用的:socket close recv( udp :recvfrom ) send (udp:sendto)
客户端:connect
服务器端:listen accept bind
tcp客户端程序流程:创建套接字socket,发起连接connect(接收到服务器端的syn+ack并发送ack返回),传输数据(recv send),关闭连接(close)
tcp服务器端流程:创建套接字socket,绑定socket到固定地址bind,监听socket (listen),接受连接(accept(接受到客户端的ack返回)),recv send close
udp客户端流程:创建套接字socket,传输数据 recvfrom sendto
udp服务器端流程:创建套接字socket,绑定socket到固定地址bind,监听socket (listen),数据传输recvfrom sendto
I/O复用:使程序能够同时监听多个文件描述符
select:给定需要监听的可读可写异常事件的文件描述符集合,以及监听的时间,返回时,内核根据就绪的事件修改对应的文件描述符集合。用户程序需要遍历所有的文件描述符集合来判断哪些事件就绪,同时由于内核修改了文件描述符集合,因此下次监听的时候,用户程序需要重新初始化需要监听的文件描述符集合
poll:给定需要监听的文件描述符以及对应的事件,在给定的监听时间结束后返回。内核修改文件描述附上实际发生的事件,用户程序通过遍历多有的文件描述符来判断哪些文件描述符上面的注册事件发生了。由于注册事件和实际发生的事件分开表示,因此不需要每次重新初始化待监听的文件描述符
epoll:需要在内核上建立一个内核事件表用来登记需要监听的文件描述符和对应的事件,监听分三步,首先建立内核事件表(epoll_create),然后登记需要监听的文件描述符和事件(epoll_ctl),最后监听(epoll_wait)。epoll_wait返回就绪的文件描述符和其对应事件(直接从内核事件表中复制),这样用户程序只需要遍历就绪的事件而不需要遍历所有的事件,提高了效率,同时用户不需要每次传入需要监听的文件描述符和事件集合。
多进程和多线程编程:
进程的创建:fork(复制进程映像,父子进程的进程映像相同,在父进程中打开的文件描述符在子进程中默认也是打开的)
exec(替换进程映像)
进程间通信:
管道:pipe调用产生两个文件描述符分别表示内核中创建的管道的两端。fp[0] fp[1],一个表示读端一个表示写端,利用fork产生子进程,在父子进程中这两个文件描述符同时保持打开,要实现从父进程向子进程传递数据,需要关闭父进程的读端fp[0],和子进程的写端fp[1],一个管道只能实现一个方向的数据传输
信号量:semget创建信号量集,semop操作信号量,semctl设置信号量
信号量的操作有两种p操作(如果信号量的值大于0则将信号量减一,如果等于0则挂起进程)v操作(如果有挂起的进程则环唤醒进程如果没有则将信号量的值加一)
共享内存:shmget创建共享内存,shmat将共享内存映射到进程的地址空间,shmdt从进程地址空间分离,shmctl对共享内存的操作。(感觉这种方法创建的空间在进程之外)
posix方法:用shm_open创建一个共享内存对象类似于文件,mmap创建一个共享内存区域并和共享内存文件描述符建立映射关系,mumap解除映射,shm_unlink删除共享内存
消息队列:msgget创建消息队列,msgsnd向消息队列中加入一条消息,msgrcv从消息队列中拿出一条消息,msgctl消息队列属性控制
ipcs命令可以查看上面的共享资源
线程的创建:pthread_create创建线程,pthread_exit线程退出,pthread_join回收线程,pthread_cancel取消线程
线程间通信:信号量,互斥锁,条件变量(当某个共享变量达到某个值的时候唤醒等待这个变量的线程)
信号量(sem_init sem_destroy sem_wait sem_post)
互斥锁(pthread_mutex_init pthread_mutex_destory pthread_mutex_lock pthread_mutex_unlock)
条件变量(pthread_cond_init pthead_cond_destory pthead_cond_wait pthead_cond_broadcast)
gdb调试:
https://www.cnblogs.com/kingos/p/4514756.html
gdb 打开调试器
file +文件名 要调试哪个文件(在编译的时候必须加-g 才能是编译得到的文件可调试 c的编译时gcc c++的编译时g++)
list 查看文件内容
b+行号 在哪一行设立一个断点
clear+行号 在哪一行删除一个断点
info breakpoint 查看哪些地方设置了断点
run 开始运行
c继续执行
n执行下一个语句
step 单步调试(会进入函数内部)
print +变量名 打印变量的值
quit 退出
调试多进程:
attach 附加到待调试进程
follow_fork_mode 设置进行fork调用之后是调试父进程还是子进程
调试多线程:
thread info显示所有子线程
thread 2 调试id为2的子线程