牛客 C++高并发服务器开发
参考笔记

  • 1 TCP三次握手
  • 2 TCP滑动窗口
  • 3 TCP四次挥手
    • 在这里插入图片描述
  • 4 TCP通信并发
  • 5 TCP状态转换
  • 6.端口复用
  • 7 I/O多路复用(I/O多路转接) (重要)
    • 7.1 select
    • 7.2 BIO 阻塞IO
    • 7.3 NIO 非阻塞IO
    • 7.4 select()工作过程分析
    • 7.5 poll()
    • 7.6 epoll() 解决了select()的所有缺点

1 TCP三次握手

TCP是一种面向连接的单播协议,在发送数据前,通信双方必须在彼此间建立一条连接。所谓的"连接”,其实是客户端和服务器的内存里保存的一份关于对方的信息,如IP地址、端口号等。

TCP可以看成是一种字节流,它会处理IP层或以下的层的丢包、重复以及错误问题。在连接的建立过程中,双方需要交换一些连接的参数。这些参数可以放在TCP头部。

TCP提供了一种可靠、面向连接、字节流、传输层的服务,采用三次握手建立一个连接。采用四次挥手来关闭一个连接。

三次握手的目的保证通信双方互相之间建立了连接

三次握手发生在客户端连接的时候,当调用connect(),底层会通过TCP协议进行三次握手。

  • 16位端口号(port number):告知主机报文段是来自哪里(源端口)以及传给哪个上层协议或应用程序(目的端口)的。进行TCP通信时,客户端通常使用系统自动选择的临时端口号。

  • 32位序号(sequence number):一次TCP通信(从TCP连接建立到断开)过程中某一个传输方向上的字节流的每个字节的编号。假设主机A和主机B进行TCP通信,A发送给B的第一个TCP报文段中,序号值被系统初始化为某个随机值ISN (Initial Sequence Number,初始序号值)。那么在该传输方向上(从A到B),后续的TCP报文段中序号值将被系统设置成ISN加上该报文段所携带数据的第一个字节在整个字节流中的偏移。例如,某个TCP 报文段传送的数据是字节流中的第1025~2048字节那么该报文段的序号值就是ISN +1025。另外一个传输方向(从B到A)的TCP报文段的序号值也具有相同的含义。

  • 32位确认号(acknowledgement number):用作对另一方发送来的TCP报文段的响应。其值是收到的TCP报文段的序号值+标志位长度(SYN,FIN)+数据长度。假设主机A和主机B进行TCP通信,那么A发送出的TCP报文段不仅携带自己的序号,而且包含对B发送来的TCP报文段的确认号。反之,B发送出的TCP报文段也同样携带自己的序号和对A发送来的报文段的确认序号。

  • 16位校验和(TCP checksum):由发送端填充,接收端对TCP报文段执行CRC算法以校验TCP报文段在传输过程中是否损坏。注意,这个校验不仅包括TCP头部,也包括数据部分
    这也是TCP可靠传输的一个重要保障。

  • 16位紧急指针(urgent pointer) :是一个正的偏移量。它和序号字段的值相加表示最后一个紧急数据的下一个字节的序号。因此,确切地说,这个字段是紧急指针相对当前序号的偏移,不妨称之为紧急偏移。TCP的紧急指针是发送端向接收端发送紧急数据的方法。

三次握手的目的保证通信双方互相之间建立了连接。含义如下:

客户端,知道自己的发送、接收功能没问题;
服务端,知道自己的发送、接收功能没问题;

客户端,还要知道服务端的发送、接收功能没问题;
服务端,还要知道客户端的发送、接收功能没问题;

三次握手,具体含义
第一次握手:客户端给服务端发一条消息,服务端接收到消息;服务端知道客户端发送功能OK,自己接收功能OK;

第二次握手:服务端给客户端回一条消息,客户端接收到消息;客户端知道自己发送、接收功能OK,也知道服务端接收、发送功能OK;

第三次握手:客户端收到服务端的应答,回一条消息,服务端收到客户端回应的消息。服务端知道自己发送、接收功能OK,也知道客户端发送、接收OK 。

第一次握手:1.客户端将SYN标志位置为12.生成一个随机的32位的序号seq=J,这个序号后边是可以携带数据(数据的大小)
第二次握手:1.服务器端接收客户端的连接:ACK=12.服务器会回发一个确认序号:ack=客户端的序号+数据长度+SYN/FIN(按一个字节算)3.服务器醋会向客户端发起连接请求:SYN=14.服务器会生成一个随机序号:seq = K
第三次握手:1.客户单应答服务器的连接请求:ACK=12.客户端回复收到了服务器端的数据: ack=服务端的序号+数据长度+SYN/FIN(按一个字节算)

2 TCP滑动窗口

滑动窗口(Sliding window)是一种流量控制技术。早期的网络通信中,通信双方不会考虑网络的拥挤情况直接发送数据。由于大家不知道网络拥塞状况,同时发送数据,导致中间节点阻塞掉包,谁也发不了数据,所以就有了滑动窗口机制来解决此问题。滑动窗口协议是用来改善吞吐量的一种技术,即容许发送方在接收任何应答之前传送附加的包。接收方告诉发送方在某一时刻能送多少包(称窗口尺寸)。

TCP中采用滑动窗口来进行传输控制,滑动窗口的大小意味着接收方还有多大的缓冲区可以用于接收数据。发送方可以通过滑动窗口的大小来确定应该发送多少字节的数据。当滑动窗口为0时,发送方一般不能再发送数据报。

滑动窗口是TCP中实现诸如ACK确认、流量控制、拥塞控制的承载结构。

窗口理解为缓冲区的大小
滑动窗口的大小会随着发送数据和接收数据而变化。
通信的双方都有发送缓冲区和接收数据的缓冲区服务器:发送缓冲区(发送缓冲区的窗口)接收缓冲区(接收缓冲区的窗口)客户端发送缓冲区(发送缓冲区的窗口)接收缓冲区(接收缓冲区的窗口)

发送方的缓冲区:白色格子:空闲的空间灰色格子:数据已经被发送出去了,但是还没有被接收紫色格子:还没有发送出去的数据接收方的缓冲区:白色格子:空闲的空间紫色格子:己辽接收到的数据

3 TCP四次挥手

四次挥手发生在断开连接的时候,在程序中当调用了close()会使用TCP协议进行四次挥手。客户端和服务器端都可以主动发起断开连接,谁先调用close()谁就是发起。

因为在TCP连接的时候,采用三次握手建立的的连接是双向的,在断开的时候需要双向断开。

什么是四次挥手
由于TCP连接是全双工的,断开一个TCP连接,需要客户端与服务器发送四个包来确认连接的断开。

简述四次挥手的过程:

因为TCP是全双工的,因此,每个方向都要单独关闭
当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,收到一个FIN只是意味着
一方向不会再收到数据了,但是这个TCP连接上仍然能够发送数据,直到这一方也发送了FIN.
首先进行关闭的一方执行主动关闭,另一方执行被动关闭.第一个关闭的最后等待2MSL


中断连接端可以是客户端,也可以是服务器端。

第一次挥手:客户端发送一个FIN=M,用来关闭客户端到服务器端的数据传送,客户端进入FIN_WAIT_1状态。意思是说"我客户端没有数据要发给你了",但是如果你服务器端还有数据没有发送完成,则不必急着关闭连接,可以继续发送数据。

第二次挥手:服务器端收到FIN后,先发送ack=M+1,告诉客户端,你的请求我收到了,但是我还没准备好,请继续你等我的消息。这个时候客户端就进入FIN_WAIT_2 状态,继续等待服务器端的FIN报文。

第三次挥手:当服务器端确定数据已发送完成,则向客户端发送FIN=N报文,告诉客户端,好了,我这边数据发完了,准备好关闭连接了。服务器端进入LAST_ACK状态。

第四次挥手:客户端收到FIN=N报文后,就知道可以关闭连接了,但是他还是不相信网络,怕服务器端不知道要关闭,所以发送ack=N+1后进入TIME_WAIT状态,如果Server端没有收到ACK则可以重传。服务器端收到ACK后,就知道可以断开连接了。客户端等待了2MSL后依然没有收到回复,则证明服务器端已正常关闭,那好,我客户端也可以关闭连接了。最终完成了四次握手。

上面是一方主动关闭,另一方被动关闭的情况,实际中还会出现同时发起主动关闭的情况,


图解三次握手和四次挥手的过程:


再摘一个图,供参考:

4 TCP通信并发

要实现TCP通信服务器处理并发的任务,使用多线程或者多进程来解决。

思路:
1.一个父进程,多个子进程
2.父进程负责等待并接受客户端的连接
3.了进程:完成通信,接受一个客户端连接,就创建一个子进程用于通信。

5 TCP状态转换


黑线是错误和异常,主要看红线和绿线;

  • 2MSL (Maximum Segment Lifetime)
    主动断开连接的一方,最后进入一个TIME_WAIT状态,这个状态会持续: 2mslo
    msl:官方建议:2分钟,实际是30s

当TCP连接主动关闭方接收到被动关闭方发送的FIN和最终的ACK后,连接的主动关闭方必须处于TIME_WAIT状态并持续2MSL时间。

这样就能够让TCP连接的主动关闭方在它发送的ACK丢失的情况下重新发送最终的ACK。

主动关闭方重新发送的最终ACK并不是因为被动关闭方重传了ACK(它们并不消耗序列号,被动关闭方也不会重传),而是因为被动关闭方重传了它的FIN。事实上,被动关闭方总是重传FIN直到它收到一个最终的ACK。

  • 半关闭
    当TCP链接中A向B发送FIN请求关闭,另一端B回应ACK之后(A端进.
    FIN_WAIT_2状态),并没有立即发送FIN给A,A方处于半连接状态(半开关),此时A可以接收B发送的数据,但是A已经不能再向B发送数据。

从程序的角度,可以使用API来控制实现半连接状态:

#include <sys/socket.h>
int shutdown(int sockfd,int how);sockfd:需要关闭的socket的描述符how:允许为shutdown操作选择以下几种方式:SHUT_RD(0):关闭sockfd上的读功能,此选项将不允许sockfd进行读操作。该套接字不再接收数据,任何当前在套接字接受缓冲区的数据将被无声的丢弃掉。SHUT_WR(1):关闭sockfd的写功能,此选项将不允许sockfd进行写操作。进程不能在对此套接字发出写操作。SHUT_RDNR(2):关闭sockfd的读写功能。相当于调用shutdown两次:首先是以SHUT_RD ,然后以SHUT_WR。

使用close中止一个连接,但它只是减少描述符的引用计数,并不直接关闭连接,只有当描述符的引用计数为0时才关闭连接。shutdown不考虑描述符的引用计数,直接关闭描述符。也可选择中止一个方向的连接,只中止读或只中止写。

注意:
1.如果有多个进程共享一个套接字,close每被调用一次,计数减1,直到计数为0时,也就是所用进程都调用了close,套接字将被释放。
2.在多进程中如果一个进程调用了shutdown(sfd, SHUT_RDWR)后,其它的进程将无法进行通信。但如果一个进程close(sfd)将不会影响到其它进程。

6.端口复用

端口复用最常用的用途是:

  • 防止服务器重启时之前绑定的端口还未释放
  • 程序突然退出而系统没有释放端口

7 I/O多路复用(I/O多路转接) (重要)

I/O多路复用使得程序能同时监听多个文件描述符,能够提高程序的性能,Linux下实现IO多路复用的系统调用主要有select.poll和epoll。

7.1 select

主旨思想:
1.首先要构造一个关于文件描述符的列表,将要监听的文件描述符添加到该列表中。

⒉调用一个系统函数,监听该列表中的文件描述符,直到这些描述符中的一个或者多个进行/O操作时,该函数才返回。

  • a.这个函数是阻塞
  • b.函数对文件描述符的检测的操作是由内核完成的

3.在返回时,它会告诉进程有多少(哪些)描述符要进行I/O操作。




7.2 BIO 阻塞IO

根本问题,阻塞。由于阻塞,新来的来的客户端就无法连接接,,,,解解这个问题,开多线程,每个线程对应一个客户端,,,但这样造成了调度资源浪费。

7.3 NIO 非阻塞IO

非阻塞IO,缺点复杂度高,假如有n个客户端,每循环内O(n)的系统调用。

7.4 select()工作过程分析

7.5 poll()

7.6 epoll() 解决了select()的所有缺点

Epoll的工作模式:

  • LT模式(水平触发)
    假设委托内核检测读事件->检测fd的读缓冲区
    读缓冲区有数据-> epoll检测到了会给用户通知

    • a.用户不读数据,数据一直在缓冲区,epoll会一直通知
    • b.用户只读了一部分数据,epoll会通知
    • c.缓冲区的数据读完了,不通知

LT(level - triggered))是缺省的工作方式,并且同时支持 block和no-block socket。在这种做法中,内核告诉你一个文件描述符是否就绪了,然后你可以对这个就绪的fd进行IO操作。如果你不作任何操作,内核还是会继续通知你的。

  • ET模式(边沿触发)
    假设委托内核检测读事件>检测fd的读缓冲区
    读缓冲区有数据- > epoll检测到了会给用户通知

    • a.用户不读数据,数据一致在缓冲区中,epoll下次检测的时候就不通知了
    • b.用户只读了一部分数据,epoll不通知
    • c.缓冲区的数据读完了,不通知

Linux C++服务器项目——网络编程2(三次握手、四次挥手、IO多路复用)相关推荐

  1. Linux C++服务器项目——网络编程1 (socket通信,服务端,客户端)

    牛客 C++高并发服务器开发 参考笔记 1.MAC地址 2 IP地址 2.1 简介 2.2 IP地址编址方式 2.3 子网掩码 3 端口 3.1 简介 3.2 端口类型 4 网络模型 4.1 OSI七 ...

  2. 一切皆socket!网络编程:三次握手 四次握手 与socket函数的关系

    转载地址:http://www.cnblogs.com/suntp/p/6434644.html 我们深谙信息交流的价值,那网络中进程之间如何通信,如我们每天打开浏览器浏览网页时,浏览器的进程怎么与w ...

  3. TCP三次握手四次挥手 TCP/UDP区别

    三次握手 第一次握手: 建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认:  SYN:同步序列编号(Synchronize Sequence Numbe ...

  4. Linux网络编程(网络七层协议,TCP/IP,三次握手四次挥手,TCP/UDP的区别)

    1.OSI 7层网络模型 1.网络七层协议 (1)OSI定义了网络互连的七层框架(物理层.数据链路层.网络层.传输层.会话层.表示层.应用层),即ISO开放互连系统参考模型. (2)各层功能定义 这里 ...

  5. java 中的网络编程(Socket、TCP三次握手四次挥手、TCP/UDP/URL)

    文章目录 前言 一.网络编程概述 二.网络通信要素概述 1.如何实现网络中的主机互相通信 2.网络通信协议 3.IP和端口号 4.InetAddress类 5.网络协议 6.TCP/IP协议簇 7.T ...

  6. Python进阶----网络通信基础 ,OSI七层协议() ,UDP和TCP的区别 , TCP/IP协议(三次握手,四次挥手)...

    Python进阶----网络通信基础 ,OSI七层协议() ,UDP和TCP的区别 , TCP/IP协议(三次握手,四次挥手) 一丶CS/BS 架构 C/S: 客户端/服务器 定义:       这里 ...

  7. python网络通信效率_Python进阶----网络通信基础 ,OSI七层协议() ,UDP和TCP的区别 , TCP/IP协议(三次握手,四次挥手)...

    Python进阶----网络通信基础 ,OSI七层协议() ,UDP和TCP的区别 , TCP/IP协议(三次握手,四次挥手) 一丶CS/BS 架构 C/S: 客户端/服务器 定义: 这里的客户端一般 ...

  8. linux 查看握手时间,实战:tcpdump抓包分析三次握手四次挥手

    本文档以实战的形式介绍tcpdump抓包分析三次握手四次挥手的过程. 执行tcpdump命令 tcpdump -n -i ens32 host 192.168.10.10 and 42.186.113 ...

  9. 在深谈TCP/IP三步握手四步挥手原理及衍生问题—长文解剖IP

    如果对网络工程基础不牢,建议通读<细说OSI七层协议模型及OSI参考模型中的数据封装过程?> 下面就是TCP/IP(Transmission Control Protoco/Interne ...

最新文章

  1. JAE京东云引擎Git上传管理代码教程和京东云数据库导入导出管理
  2. vmware让虚拟机内外网络可互访
  3. 【 FPGA 】FIR 滤波器之多相抽取器(Polyphase Decimator)
  4. TFS 2010 使用手册(二)项目集合与项目
  5. 剪切工具怎么用_原创度检测工具是怎么用的?优质的内容更容易获得平台推荐...
  6. mysql 和 oracle 的一些区别
  7. python多进程优化_如何利用多进程优化Python视频应用
  8. 历经5代跨越25年的RTC架构演化史
  9. 软件项目开发之 软件过程RUP初探
  10. 2016蓝桥杯省赛---java---B---8(四平方和)
  11. vue-cli-service不是内部或外部命令,也不是可运行的程序
  12. 前端:CSS/08/框架
  13. Pytest之自定义mark
  14. N1盒子刷入codesys当PLC使用
  15. 按头安利 好看又实用的手绘图标素材看这里
  16. VirtualBox 虚拟机安装黑群晖
  17. t450加固态硬盘教程_ThinkPad T450 开箱安装内存SSD升级Windows10过程小记-5X兴趣社区...
  18. python的list怎么取后几个元素
  19. 【力扣刷题】121.买卖股票的最好时机(python)
  20. Android AMS(android 11)

热门文章

  1. 2013年6月《棱镜透视了什么?》
  2. python 知识成长(持续更新)
  3. 根据文件头检测文件类型的完整代码
  4. 懒到骨子里了,我在CSDN写文章都懒得自己写了,基于selenium模拟写文章
  5. 实践任务:项目介绍与项目准备+制作网页头部和导航+制作banner和最新更新栏目+制作苹果之家栏目+制作底部版权区域与CSS代码优化+制作Apple独家栏目
  6. 希捷硬盘升级固件方法
  7. CodeM资格赛D 送外卖 题解
  8. 用Python中的马尔科夫链进行营销渠道归因
  9. 无线控制需要服务器,H3C无线控制器与LDAP服务器配合进行远程Portal认证可以做么?...
  10. wireshark检测广播风暴_带你走进网络世界:一文读懂广播风暴