《后台开发:核心技术与应用实践》第六章
Posted alwayszzj
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《后台开发:核心技术与应用实践》第六章相关的知识,希望对你有一定的参考价值。
第6章 TCP协议
6.1TCP协议
网络模型
ios七层网络模型 | 五层网络模型 | TCP/IP分层模型 |
---|---|---|
应用层 | ||
表示层 | ||
会话层 | 应用层 | 应用层 |
传输层 | 传输层 | 传输层 |
网络层 | 网络层 | 网络层 |
数据链路层 | 数据链路层 | 网络接口 |
物理层 | 物理层 |
TCP/IP协议
网络 | 协议 |
---|---|
网络接口 | ARP |
网络层 | IP、RIP、ICMP |
传输层 | TCP、UDP |
应用层 | FTP、HTTP、telnet |
TCP头部
1.16位端口号:告知主机该报文是来自哪里(源端口)以及传给哪个上层协议或应用程序(目的端口)的。
2.32位序号(sequence number):一次TCP通信过程中某个传输方向上的字节流的每个字节的编号。
3.32位确认号(acknowledgement number):用作对另一方发送来的TCP报文段的响应
4.4位头部:标识该TCP头部有多少个4字节,共表示最长15*4=60字节。
5.6位标志位:6位标志。URG(紧急指针是否有效)ACK(表示确认号是否有效)PSH(提示接收端应用程序应该立即从TCP接收缓冲区读走数据)RST(表示要求对方重新建立连接)SYN(表示请求建立一个连接)FIN(表示通知对方本端要关闭连接)
6.16位窗口大小:TCP流量控制,窗口指的是接收通告窗口,告诉对方本端TCP接收缓冲区还能容纳多少字节的数据。
7.16位校验和大小:对TCP报文段执行CRC算法以检验TCP报文段在传输过程中是否损坏。
8.16位紧急指针:一个正的偏移量,它和序号段的值相加表示最后一个紧急数据的下一字节的序号
三次握手过程
四次挥手过程
TCP连接状态
- CLOSED:初始状态
- LISTEN:表示服务器某个socket处于监听状态,可以接受连接
- SYN_SENT:在服务端监听后,客户端socket执行连接,客户端发送SYN报文,此时客户端进入SYN_SENT状态,等待服务端的确认
- SYN_RCVD:表示服务端收到了SYN报文
- ESTABLISHED:连接已经建立
- FIN_WAIT_1:建立连接之后,其中一方请求终止连接,等待对方的FIN报文
- FIN_WAIT_2:半关闭状态,即有一方要求关闭连接,但另外告诉对方:我暂时有还有点数据需要传送给,请稍后关闭连接
- TIME_WAIT:表示收到了对方的FIN报文,并发送出了ACK报文。、等待足够的时间以确保远程TCP接收到连接中断请求的确认。
- CLOSING:比较少见,双方都在关闭socket连接
- CLOSED_WAIT:等待关闭
- LAST_ACK:被动关闭一方在发送FIN报文后,最后等待对方的ACK报文。
- CLOSED:当收到ACK报文后,即可以进入到CLOSED可用状态
TCP超时重传
TCP每发送一个报文段,就对这个报文段设置一次计时器,只要计时器设置的重传时间到了,但还没有收到确认,就要重传这一报文段,这个就叫作“超时重传”。
关键参数RTO :发送端发送数据后、重传数据前等待接收方收到该数据报文的ack时间。
设置长了:重发就会很慢,没有效率,性能差
设置短了:重发就快,会增加网络拥塞,导致更多的超时。
引入RTT(连接往返时间)动态设置
TCP滑动窗口的两个作用
- 提供TCP的可靠性
- 流量控制:窗口大小随链路变化
滑动窗口机制:TCP是双工的协议,会话的双方都可以同时接收、发送数据。TCP会话的双方各自维护一个“发送窗口”和一个”接收窗口“。TCP的窗口滑动技术通过动态改变窗口的大小来调节两台主机之间数据传输。
TCP拥塞控制
拥塞控制就是防止过多的数据注入网络中,这样可以使网络中的路由器或链路不过载。拥塞控制是个全局性的过程,和流量控制不同,流量控制点对点通信量的控制。
四个核心算法:
慢开始:先探测一下网络的拥塞程度,由小到大逐渐增加拥塞窗口的大小
拥塞避免:让拥塞窗口缓慢增长,每经过一个往返时间,拥塞窗口+1
快速重传:要求接收方在收到一个失序的报文段后就立即发出重复确认
快速恢复
6.2TCP网络编程API
TCP交互流程
socket-> bind->listen->accept->recv->close
(创建socket 绑定socket和端口号 监听端口号 接收来自客户端的连接请求 从socket中读取字符 关闭socket)
socket->connect->send->close
(创建socket 连接指定计算机的端口 向socket中写入信息 关闭socket)
基本的socket接口函数
1.socket函数
int socket(int domain,int type,int protocol)
2.bind函数
int bind(int sockfd,const struct sockaddr *addr,socklen_t addrlen);
3.listen函数和connect函数
int listen(int sockfd,int backlog);
int connect(int sockfd,const struct sockaddr *addr,socklen_t addrlen);
4.accept函数
int accept(int sockfd,struct sockaddr *addr,socklen_t *addrlen);
5.read和write函数
ssize_t read(int fd,void *buf,size_t count);
ssize_t write(int fd,const void *buf,size_t count);
6.close函数
#include<unistd.h>
int close(int fd);
6.3 实现一个TCPserver
6.4 TCP协议选项
6.5网络字节序和主机序
字节序:Little Endian Big Endian(所有的网络协议)
当两台采用不同字节序的主机通信时,在发送数据之前都必须经过字节序的转换成为网络字节序后再进行传输。
6.6封包和解包
- TCP/IP 网络数据以流的方式传输,数据流是由包组成,如何判定接收方收到的包是否是一个完整的包就要在发送时对包进行处理,这就是封包技术。封包就是给一段数据加上包头,这样一来数据包就分为包头和包体两部分内容了
- 包头其实上是个大小固定的结构体,其中有个结构体成员变量表示包体的长度,这是个很重要的变量,其他的结构体成员可根据需要自己定义.根据包头长度固定以及包头中含有包体长度的变量就能正确的拆分出一个完整的数据包
- 利用底层的缓冲区来进行拆包时,由于TCP也维护了一个缓冲区,所以可以利用TCP的缓冲区来缓存发送的数据,这样一来就不需要为每一个连接分配一个缓冲区了.对于利用缓存区来拆包,就是循环不停地接收包头给出的数据,直到收够为止,这就是一个完整的TCP包。
以上是关于《后台开发:核心技术与应用实践》第六章的主要内容,如果未能解决你的问题,请参考以下文章
强烈推荐一本今年八月份的新书《后台开发:核心技术与应用实践》,作者腾讯资深后台开发工程师徐晓鑫
做后台开发用到的技能都在这儿——《后台开发:核心技术与应用实践》