一、网络编程//目的是解决进程间在不同主机上的通信
1.名词解释:
(1)网络:把不同的计算机连接起来就构成了网络
(2)网络设备:路由器、交换机
(3)通信介质:双绞线、光纤、无线电磁波
(4)互联网:网络和网络之间连接起来的称为互联网
(5)ip : 用来标识唯一一台主机//ipv4:32位,具有逻辑结构
(6)mac地址:物理地址,负责数据链路层上的地址,用来定义网络设备的位置,由网卡决定,一旦出厂不可更改//48位
(7)端口:在主机上唯一标识一个进程的//整型值
(8)ip+端口号可以确定网络上唯一的进程
(9)协议:共同遵守的约定/标准
(10)OSI七层模型: TCP/IP四层模型:
应用层 应用层 //http、ftp等协议
表示层
会话层
传输层 传输层 //tcp、udp等协议
网络层 网络层 //ip、icmp等协议
数据层 数据层 //arp、rarp等协议
物理层
二、传输层的tcp和udp协议
1、tcp协议和udp协议的区别:
(1)Tcp协议:面向连接的、可靠的流式服务
Udp协议:无连接的、不可靠的数据报服务
(2)udp没有拥塞控制,因此网络上出现拥塞不会使源主机的发送速率降低
//对实用的ip电话、实时视频会议等很有用
(3)tcp的连接只能是点到点的;udp支持一对一、一对多、多对一和多对多的交
互通信
(4)tcp首部开销20个字节,udp首部开销8个字节
(5)Tcp的逻辑通信信道是全双工的可靠信道,udp是不可靠信道
2、TCP协议
(1)编程流程:
(2)TCP传输可靠的特性:
首先,TCP协议采用发送应答机制,即发送端的每个TCP报文段必须得到
接收方的应答才确认传输成功;其次,TCP协议采用超时重传机制,发送
端在发送出一个TCP报文段之后启动定时器,如果在一定的时间内未收到
应答,则重新发送该报文段;最后,由于TCP报文段是以IP数据报发送的,
而Ip数据报收到达接受端可能是乱序重复的,所以TCP报文段会对接收到
的进行重新整理后交给应用层。
(3)流式服务的特点:发送端执行的写操作次数与接收端执行的读操作次数之间没有任何数量关系
发送端 接受端
当recv()返回值为0时则代表对方已关闭,当send()返回值成功时也不能代表数
据已发送过去,只能表示数据已存放到TCP发送缓冲区
(4)状态转移图:
注:实线表示典型的客户端连接的转态转移
虚线表示典型的服务器端连接的状态转移
服务器端连接的状态转移:
服务器通过listen系统调用进入LISTEN状态,被动的等待客户端连接,当
服务器一旦监听到某个连接请求,就将该连接放入内核等待队列中,并向
客户端发送带SYN标志的确认报文段,使得连接出去SYN_RCVD状态。当
服务器端成功的接收到客户端发送回的确认报文段,该连接转移到ESTABLISHED状态(此状态表示三次握手状态已完成,连接建立成功)
当客户端发起关闭连接时,服务器通过返回确认报文段使连接进入CLOSE_
WAIT状态(等待服务器应用程序关闭连接),当服务器检测到客户端关闭连接后,也会立即给客户端发送一个结束报文段来关闭连接,从而使连接转移到LAST_ACK状态
客户端连接的状态转移:
客户端通过connect系统调用主动和服务器建立连接,connect系统调用首先给服务器端发送一个同步报文段,是连接转移到SYN_SENT状态。Connect系统调用可能会因两个原因失败:(连接的目标端口不存在或者该端口被占用或目标端口存在但超时时间内未收到服务器的确认报文段)
如果调用失败则返回初始状态CLOSED状态,成功则连接转移到ESTABLISHED状态;
当客户端主动执行关闭时,会向服务器发送一个结束报文段,同时连接会进入FIN_WAIT_1状态,如果此时的客户端收到服务器专门用于确认 报文段,则连接转移到FIN_WAIT_2状态,服务器端同时也处于COLSE_WAIT状态,这一对状态可能发生半关闭状态,如果此时服务器也关闭连接,则客户端给予确认并进入TIME_WAIT状态。
如果处于FIN_WAIT_1状态的服务器能够直接收到带确认信息的结束报文段(而不是先收到确认报文段,再收到结束报文段),此时客户端从FIN_WAIT_1状态直接进入TIME_WAIT状态。
当处于FIN_WAIT_2状态的客户端需要等待服务器发送结束报文段才能转
到TIME_WAIT状态,否则将一直停留到这个状态,如果不是为了在半关
闭状态下继续收发数据,长时间的停留在此状态时会发生:客户端执行半
关闭后,未等服务器关闭连接就强行退出,此时的客户端连接将有内核来
接管,称为孤儿连接。为了避免孤儿连接长时间存在内核中,定义了两个
内核变量,一个用来指定内核能接管的孤儿链接数目,一个用来连接孤儿
连接在内核中存活的时间
TCP建连接和断开连接服务器和客户端的状态
TIME_WAIT状态:
由上图可知在客户端连接在收到服务器的结束报文端之后并没有
直接进入CLOSED状态,而是出去TIME_WAIT状态,在这个状态
客户端连接要等待一段2MSL(MSL:报文段最大生存时间)//2min的
时间,才能完全关闭;
存在的原因:
(1)可靠的终止了TCP连接
(2)保证让迟来的TCP报文段有足够的时间被识别丢弃
(5)解决connect连接阻塞的问题:
A.设置超时时间,超过时间连接则失败
(6)程序结束并不意味着连接也结束,当close后,进程不会直接结束,状态还没有结束,直到四次挥手 结束后才结束;
(7)处理粘包问题:
A.黏包问题:TCP黏包问题是因为发送方把若干数据发送,接收方收到数据时黏在一包,从接收缓 冲区来看,后一包的数据黏在前一包的尾部。
B.出现的原因:
发送方问题:首先TCP会默认使用Nagle算法,Nagle算法主要做两件事。 第一:上一包分组得到确认,才会发送下一分组。 第二:收集多个小组,在一个确认到来时一起发送。由此可见Nagle算法会使得数据在发送方造成黏包问题 。
接收方问题:TCP接收方接收到分组的时候,并不会立刻提交到应用
层、处理,收到的数据放在接收缓存里面,然后应用程序会主动从接受缓存里读取接收的分组,这样以来,如果TCP接收分组的速度大于应用读取分组的速度,多个包的数据会存至缓存区里面,应用读取数据就可能会产生黏包问题。
C.什么时候处理黏包问题
(1)如果每次利用TCP发送数据,就与对方建立连接,然后发送完数据就关闭连接这样就不会出现黏包问题(大家都知道只发送一个数据包)
(2)如果发送的数据无结构,比如文件的传输,只要发送方一直发送,接收方只管接收到储存的数据,此时也不用考虑黏包问题。
(3)如果在连接的一段时间内发送的数据毫无关系,我们就要考虑黏包问题了。 比如:你要发送一段话 I love you. I want play. 如果产生了黏包问题,接收方可能会傻眼,你让我干啥?所以一般会在数据前加一个长度之类的包,确保接收。
D.处理黏包现象
(1)发送方:发送方产生黏包问题的主要原因在于Nagle算法,我们可以通过关闭Nagle算法来解决,使用TCP_NODELAY选项来关闭Nagle算法。
(2)接收方:由于TCP没有处理接收方黏包现象的机制,我们只能在应用层进行处理。
(3)应用层处理:解决方法就是循环处理:应用程序在处理从缓存读来的分组时,读完一条数据时,就应该循环读下一条数据,直到所有的数据都被处理;但是如何判断每条数据的长度呢?
两种途径:
1)格式化数据:每条数据有固定的格式(开始符、结束符),这种方法简单易行,但选择开始符和结束符的时候一定要注意每条数据的内部一定不能出现开始符或结结束符。
2)发送长度:发送每条数据的时候,将数据的长度一并发送,比如可以选择每条数据的前4位是数据的长度,应用层处理时可以根据长度来判断每条数据的开始和结束。
(8)抓包:tcpdump 命令
(9)复位报文段:
在某些特殊条件下,TCP连接的一端会向另一端发送含RST标志的报文段,
即为复位报文段,已通知对方关闭连接或者重新建立连接
产生复位报文段的三种情况:
A. 访问不存在的端口:当客户端程序向服务器的某个端口发起连接时,由于端口处于 WAIT_TIME状态的连接被占用,所以客户端程序也将收到复位报文段
B. 异常终止连接:TCP提供了异常终止一个连接的方法,即给对方发送一个
复位报文段,发送端所有排队等待发送的数据都将被丢弃
C. 处理半打开连接:半打开连接状态:服务器(或客户端)关闭或者异常
终止了连接,而对方没有接收到结束报文段(例如网络故障),此时的
客户端(或服务器)还维持着原来的连接,即使重启后也没有该连接的任
何消息;若处于半打开连接则需要对方回应一个复位报文
(10)TCP的应答确认机制:
A. 超时重传:在异常网络状况下,为保证可靠的服务,TCP服务必须能够重传超时时间内未收到 确认的TCP报文段,为此,TCP模块为每个报文段设置了一个重传定时器,在第一次报文段被 发送时启动,如果超时间内未收到确认的应答,将重传TCP报文段并重置定时器
B. 拥塞控制:为提高网络利用率,降低丢包率,证网络资源对每条数据流的的公平性产生了拥塞 控制;
分为四个部分:慢启动,拥塞避免,快速恢复,快速重传
3、UDP协议
(1)编程流程:
(2)无连接的特性:
A.可以允许一个服务器连接的客户端
B.不需要连接,所有关闭后再次开启后依然可以正常接收和发送消息
(3)数据报的特点:只可接收一次
三、应用层的http协议
1.http协议:超文本传输协议;端口号:80
2.http请求方法:
3.http五种状态
4.长链接:经过三次握手以及应答确认后没有close的为长链接
短链接:经过三次握手以及应答确认后就close的为短链接
四、I/O复用//select、poll、epoll
1. I/O复用能是得程序能同时监听多个文件描述符;
I/O复用虽然能够同时监听多个文件描述符,但本身是阻塞的,并且当多个文件描
述符就绪的时,如果不采取额外的措施,程序只能按顺序依次处理其中的每个文件
描述符,从而使得服务器程序串行工作的,实现并发必须使用多线程或多进程等
编程手段
2.I/O复用技术的情况:
A.客户端程序要同时处理多个socket(例如:非阻塞的connect技术)
B.客户端程序要同时处理用户输入和网络连接(例如:聊天室程序)
C.TCP服务器要同时处理监听socket和连接socket(I/O复用使用最多的场所)
D.服务器要同时处理TCP请求和UDP请求
E.服务器要同时监听多个端口,或者处理多种服务
3.实现I/O复用的三个系统调用:
A.select : 在一段指定的时间内,监听用户感兴趣的文件描述上的可读、可写、异常
等事件
nfds : 指定被监听的文件描述符的总数,一般设置为select监听的所有文件
描述符中的最大值加1,因为文件描述符是从0开始技术的;
readfds,writefds和exceptfds参数分别指向可读,可写和异常事件对应的文
件描述符集合,通过这3个参数传入自己感兴趣的文件描述符,
select调用返回就绪文件描述符的个数,内核将修改它们来通知应用程序哪些文件描述;
文件描述符就绪时socket可读的条件:
(1)监听套接字sockfd,当connect连接时
(2)连接套接字c,客户端send()发送数据时
(3)客户端close(),关闭连接
B.poll:类似于select,是在指定时间内轮询一定数量的文件描述符,以测试其中是否
有就绪者 ;
fds:是一个指向所有我们感兴趣的文件描述符上发生的事件的数组
nfds: 指定被监听事件集合fds的大小
timeout : 指poll的超时值,当为-1时,将永远阻塞,直到某个时间发生
当为0时,poll调用将立即返回
C.epoll:是linux中特有的I/O复用函数,是使用一组函数来完成任务的,
epoll将用户关心的文件描述符放在内核里的一个事件表中,从而无须像select和poll每次调用都要重复传入文件描述符集或事件集,但epoll需要使用一个额外的文件描述符来唯一标识内核中的事件表
文件描述符的使用:epoll_create() //创建内核事表
epoll_ctl()//添加或移除或修改文件描述符
epoll_wait()//在一段超时时间内等待一组文件描述符 上的事件
4. 三种系统调用的比较:
共同点:三种系统调用都能同时监听多个文件描述符,它们将等待由timeout参数指定的超时时间,直 到一个或者多个文件描述符上有事件发生时返回,返回值为就绪的文件描述符的数量;
区别:
5.ET和LT模式
LT模式是默认的工作模式:当检测到其上有时间放生并将此事件通知应用程序后,应用程序可以不立即处理该事件,当下次调用时依然会向应用程序继续通知此事件,直到该事件被处理;
ET模式:当检测到有事件发生时并将此事件通知应用程序后,应用程序必须立即处理该事件,因为后续的调用不会再继续通知,由于ET模式在很大程度上降低了一个时间被重复触发的次数,因此效率高于LT模式;
五、守护进程
1. 特点:
A. 运行周期时间长
B. 在后台运行,不需要和用户进行交互
2. 会话:任务和用户之间建立的一个连接
3. 进程组:会话管理的进程组
4. 守护进程的编程流程:
A. fork复制子进程,退出父进程
B. Setsid()//创建新会话;调用该函数的前提必须是当前进程且不能是组长进程
C. Fork ()//退出父进程//为确保失去组长、首进程的身份,杜绝和其他终端关联
D. Chdir(“/”)//移到根目录下,防止被卸载
E. Umask(0);//失去权限,0代表什么作用都没有,起保护作用