相关推荐
联系我们/Contact
通信主页 > 通信 >

TCP Socket通讯周密历程

文章作者:  发布日期:2019-12-01 15:13

  

TCP Socket通讯周密历程

TCP Socket通讯周密历程

  就会仅将1~12这段数据再次发送给Client,当Server在RTT之前收到Client对这段数据的ACK, 驱动处理接收到的数据包,解封装后,发现是一个要访问本机80套接字的SYN请求,于是内核检查socket set发现有这样的监听 实际上一个数据包的大小是由网卡上的MTU值决定,默认MTU是1500个字节,去掉TCP/IP协议栈 HTTP会话连接,Worker进程分析该请求后,是要请求静态网页数据,接着向内核发起I/O请求,并告知 它将调用select()函数,此函数会发起系统调用来获取内核管理的socket set,并检查其中自己所关心的socket是否处于就绪态, 都耗尽,CPU会将httpd从CPU上转入内存处于睡眠,等待下次被调度到CPU上执行; 原理的人,有更多参考,能更快明了一个Client发送一个访问Web服务器的请求,到底WebServer如何处理接收 下面说明listen函数,已httpd为参考来说明,这样更便于说明问题;另外下面说明并不一定完全正确,多数是根据我的理解 于是根据请求报文中的 {源IP,源Port,目标IP,目标Port,协议} 去遍历查找socket set,若找到对应的专用socket,则将数据 内核还会在连接未完成队列(syn queue)中为这个连接创建一个新项目,并设置为SYN_RECV状态。 /* 假定已经建立UDP连接,具体过程不写,简单,当然TCP也同理,主机ip和port都已经给定,要写的文件已经打开 套接字,于是内核将SYN数据复制到Kernel buffer中,进行进一步处理(如判断SYN是否合理),然后准备SYN+ACK数据完成 文件内容的获取任务。写操作也是一样,待写入的buffer在内核空间不能直接访问,必须要先拷贝至内核 listen系统调用会向内核管理的socket set(集合)中注册自己的监听套接字,然后返回,此时作为httpd的perforce模型的话, 3次握手过程中的所有连接,但是队列中的每个连接分为两种状态:syn-recv和established。 对比两种方式不难发现,Sendfile方式更高效,因为它去掉了I/O请求中两次COPY的过程,在高并发的场景中是非常高效的。 CPU上执行,然后httpd子进程开始将数据封装上http首部,构建成响应报文后,再次发起系统调用,让内核将数据复制到 拷贝到socket buffer中,并将专用socket的状态设置为可读,然后,内核进入睡眠,CPU继续挂起的任务,当httpd的子进程 更高级的网络I/O模型是AIO,其实现原理很便于说明,但细节我理解不深: 页缓存中数据页再次拷贝到内存对应的用户空间中。这样,通过了两次数据拷贝过程,才能完成进程对 窗口大小(Window Size)以及Client的源IP和源端口,这是服务器端的监听套接字就可以构建成完整的 将自行调度磁盘驱动读取磁盘数据,并等待磁盘驱动完成数据从磁盘拷贝到内核kernel buffer中,再这期间kernel将被阻塞, Client解包后,发现这个序列号是13-17,然后,Client就会给Server发送一个ACK报文,这个报文 3、inode在address_space上查找要请求的文件页是否已经缓存在页缓存中。如果存在,则直接 核心内存区中的指定地址段中,然后DMA芯片就开始复制,CPU重新恢复挂起的进程,继续处理,当网卡DMA芯片再次发送 维护的socket set中80监听套接字的状态更为为可读,随后内核让出CPU,进入睡眠,CPU继续将挂起任务载入CPU上执行, 相对于同步IO,异步IO不是顺序执行。用户进程进行aio_read系统调用之后,无论内核数据是否准备好,都会直接 模型)完成后,通知Worker进程Worker进程对数据做处理后,接着又向内核发起请求,要求内核将处理后的 指定的协议类型,五元组中就有了其中3个元组。即:{protocal,src_addr,src_port} 但是,常见到有些服务程序可以 调度TCP/IP协议栈驱动对报文做TCP首部,IP首部,链路层帧头等封装,最终这个数据包构建完成,被内核发往网卡的缓冲区 若CPU时间片用完,则将其转入内存进入睡眠,继续下一个用户空间的进程,假设此时调度httpd进程到CPU上执行,它依然 这篇博文对我的启发很大,但文中比较核心一些东西说明的不是非常详细,导致整片文章对于初学者还是 从磁盘到用户主存的一次数据拷贝过程。说白了,mmap的关键点是实现了用户空间和内核空间的数据直接 返回,不会阻塞用户进程,·人社部:邦度职业才力准绳2019-11-24,然后用户进程可以继续接受新的连接请求。等到socket数据准备好了,内核会直接复制 解除阻塞,调用recvform系统调用,读取数据,此时内核会被唤醒,完成将socket buffer中的数据拷贝到该进程的的内存 上面描述了select()系统函数,这是最简单的一种多路复用I/O调用,还有poll和epoll,这两个系统调用,也属于多路复用I/O 专用连接套接字,接着将该套接字注册到内核管理的socket set中,最后将该专用连接套接字返回,接着内核进入睡眠, 中的数据拷贝到自己的内存空间中,于是CPU再次将其挂起,内核完成拷贝后,再次进入睡眠,httpd子进程再次被调到 中指定的内存区中,然后,内核进入睡眠,CPU继续调度其他进程到CPU上执行。 但是若磁盘上没有DMA芯片,那么内核 常规文件系统操作(调用read/fread等类函数)中,函数的调用过程: 发现Client还是没有对1~12这段数据做确认,于是知道第一个报文在网络中传输时丢包了,然后 任何文件拷贝操作。而之后访问数据时发现内存中并无数据而发起的缺页异常的过程(即:从物理内存的缓冲区 此篇是TCP深入刨析的上篇,核心点是说明Clinet和Server如何完成TCP三次握手。 多少数据,假设网络状况不是很好,第一个包在传输过程中丢失了,Client收到了第二个报文, 就拿硬盘来说,CPU需要读磁盘中的一段数据时,它发现磁盘支持DMA,则CPU会授权给DMA允许访问系统总线, 因为CPU在制造时,就设定了只要开机,CPU首先去读取RAM中0地址开始的连续的1M区域,来完成 假设Server要传递给Client的数据量很大,被拆分成了多个包,这里仅以两个为例说明, 函数的监听对象。绑定了地址和端口的套接字就有了源地址和源端口(对服务器自身来说是源),再加上通过配置文件中 Sendfile方式:在这种方式下,当网卡接收到数据流后,发送中断给内核,内核处理后通知网卡将数据发给80 Socket 能装多少数据,但这个还是额定数据量,正式往数据包中装数据还要看窗口大小(window size),它是 专用连接套接字,即五个关键元素组成了新的socket。当然Client也会生成本次于Server通信的专用 总结来说,常规文件操作为了提高读写效率和保护磁盘,使用了页缓存机制。这样造成读文件时需要 磁盘请求数据,得到数据后,直接将用户请求的数据封装HTTP头,TCP头,IP头,数据连接层头, 已完成连接队列中与自己建立连接的ClientInfo信息取出来,并删除队列中的信息,然后根据监听套接字,生成一个新的 第一个报文总长度为12个字,假设已经满了,然后又生成了第二个数据包长度5个字, 后经过TCP/IP协议栈驱动封装IP头,链路层帧头,最终这个数据被写入到send buffer中,并立即被复制到网卡传送出去,同时 当然不是,DMA的总线是很窄的,因此为了让DMA可访问内存,系统在设计时,就将RAM中低地址中 并告诉它将磁盘中的那部分数据放到内存中指定的地方,接着CPU就不管了,由DMA来完成数据搬运,并在完成时, 到请求报文,并最终完成整个通信过程,这篇文章将深入说明,但由于本人能力有限,很多理解是自己通过对CPU 模型,但poll和select基本类似,由于能力有限,对它们之间的区别理解很浅薄,仅知道它们在获取socket set时,似乎select 首先,服务器网卡接收到数据流后,会立刻给CPU发送中断信号,CPU收到后,会立即将手头正在处理的事务 配置监听多个地址、端口实现多实例。这实际上就是通过多次socket()+bind()系统调用生成并绑定多个套接字实现的。 服务程序通过分析配置文件,从中解析出想要监听的地址和端口,再加上可以通过socket()函数生成的套接字sockfd, 推演出来的,所以下面说明仅供参考,希望大牛路过,能给予指点,不要让我误人子弟了。 一个是协议TCP/UDP.很多时候,内核其实根据AF_INET和SOCK_STREAM就可以推演出应该使用TCP,因此 中等待发送,当然若网卡上有DMA芯片,内核依然可让DMA芯片来复制数据,完成发生,自己就去睡眠。若没有就只能自己干。 是用列表方式,而poll是链表方式,似乎于此有关,导致poll没有最大1024的限制,而select因为在kernel编译时,就设置其 网站主页资源,于是再次发起系统调用,获取磁盘中存储的主页数据,此时内核被唤醒,然后内核调度磁盘驱动,若该磁盘 若此时httpd的CPU时间片用完了,CPU将会把httpd转入内核睡眠,然后继续其它用户空间的进程;假如此刻Client 80 Socket的应用程序这时,Nginx的Master进程监听到连接请求,并将该连接请求将给Worker进程,来建立 先将文件页从磁盘拷贝到页缓存中,由于页缓存处在内核空间,不能被用户进程直接寻址,所以还需要将 1. CPU通过32根线G的内存空间,那DMA要访问内存也需要32根线吗? 仅对13-17段数据做确认,Server收到后,过了最大RTT(数据包从Server到Client直接最大往返时间) 而使用mmap操作文件中,创建新的虚拟内存区域和建立文件磁盘地址和虚拟内存区域映射这两步,没有 处理BIOS映射到里面的指令,实现开机自检。DMA设计时也是会去访问内存中固定的地址区域,实现 MTU(最大传输单元): 现在网络中所有设备都默认是1500字节,一个数据包在网络中传输最大必须 这时它们的序列号需要注意,你会发现其实序列号就是传输数据量的说明,即我这次给你传了 CPU再次调度httpd进入CPU上执行,httpd获取到专用连接套接字的文件描述符后,将其分配其中一个子进程,由子进程 是发起select系统调用,此时内核被唤醒,httpd被挂起,内核将根据select的要求,返回内核中socket set的全部状态集, 【 注意:内核任何时候与进程交换并传递数据时,采用的方式都时Copy,除非指定使用共享内存。】 该请求准备Buffer,并向磁盘请求数据,通常由DMA(直接内存访问)控制芯片接收内核请求(请求中通常会包含 正常情况下:当用户发来请求后,内核收到网卡中断处理数据流,判断为http数据流,告知将该数据流将给监听在 #ack=1,是假设Server三次握手最后一次传递的seq=0,我要对它发给我的数据做确认 socket buffer中的数据复制到用户进程空间后,内核才会找到用户进程留下的联系方式(即:通知信号)向进程发送通知。 关于epoll我的理解也不是很深刻,仅做以下说明,但理解poll和epoll的前提,还是要先理解select. 上监听的应用程序接着,Nginx的Master进程监听到连接请求,并负责向该请求分配Worker进程,来建立 2、内核通过查找进程文件符表,定位到内核已打开文件集上的文件信息,从而找到此文件的inode。 TCP深入刨析是下篇,核心点是说明Client和Server是如何完成数据传输的。 Http会话响应用户,通过解析请求发现用户请求的是静态网页,接着Worker请求向内核发起I/O请求,内核为 被调到到CPU上执行时,它通过select系统调用去检查自己监听的专用套接字时,发现自己关心的套接字为可读,于是立即 空间中,然后内核进入睡眠,CPU将httpd子进程调度到CPU上继续执行,httpd子进程读取数据,分析后知道用户要请求 最大值为1024,即只能同时接收1024个连接,但具体理解不深,若有大牛知道,也希望能分享博文。 当客户端与服务器通过三次握手建链,同步了TCP保障会话的状态序列号(Sequence Number), 就可以使用bind()函数将这个套接字绑定到要监听的地址和端口组合addr:port上。绑定了端口的套接字可以作为listen() 注意:sendfile:仅支持很小的文件直接在内核封装并响应用户,而sendfile64则支持更大的文件在内核中直接封装并响应用户。 中断告诉CPU我复制完了,此时CPU将立即挂载正在处理的进程,并激活内核,内核获得CPU控制权后,启动TCP/IP协议栈 的一段空间预留个DMA使用,它通常是16M;其中RAM的起始区中第一个1M区域是固定给BIOS使用的, 请求网站主页的数据包到达Server网卡了,网卡依然会采用上面的动作,内核依然会被唤醒,然后内核会调度TCP/IP协议 仔细结合上面对listen,select函数的说明,在参考这个两段代码,再去细细思考整个TCP通信过程, 内存,网络的理解推演出来的,没有很确凿的证据证明,也希望大牛路过,多给予指教,不要让我误人子弟了。 4、如果不存在,则通过inode定位到文件磁盘地址,将数据从磁盘复制到页缓存。之后再次发起 处理数据包,当解封装后,发现这个数据包是ACK报文,并且数据段大于0,此时内核知道这是一个已经完成的连接请求数据包, 但分为两种状态),实际目前这种是BSD衍生的一种套接字类型,它采用了一个队列,在这单个队列中存放 对linux文件系统不了解的朋友,请参阅我之前写的博文《从内核文件系统看文件读写过程》,我们首先简单的回顾一下 让DMA将数据Copy到那段Buffer空间),并从磁盘中读取数据,并Copy到Buffer中,完成后,向内核发送中断信号, 【注意:这里方式实现起来极其复杂,但是Nginx是完全支持这个方式的。】 内核这是请求静态页面的,你直接将数据封装HTTP包响应用户即可,不需在把数据给我了。接着内核向 FD_ZERO( //每次循环都要清空集合,否则不能检测描述符变化 Linux Kernel2.2以前,backlog 用于设置上图中未完成和已完成队列的最大总长度(实际上是只有一个队列, 高效传输。但需要注意的是,每次系统要DMA工作前,都会事先腾出DMA将访问的内存区域。 的最大长度,默认为128,如果backlog参数大于somaxconn,则backlog会被截短为该硬限制值。 上面有DMA芯片,则内核会直接告诉DMA芯片,你将磁盘中指定柱面,指定扇区,指定磁道上的数据复制到指定的DMA_ZOME 难度太大,这篇文章引用了部分该文中的内容,主要是为了能够让整篇文章能连贯,一便让更多想要深入计算机 {}#这部分,应该可填充下面这段代码,所以可参考下面的代码。【我并不是很懂】 封装头部大概是1446个字节,然后还要去掉上层不同协议封装的头部字节数,剩下才是这个数据包实际 #Server是发送数据者,它知道自己发了那些数据,Server看到18,对比发送列表,1~12,13~17, 以上描述就是HTTP通信的一个缩影。【文末有两段代码,可合起来看,基本就是类似httpd的代码实现,摘录仅为了方便理解 这里不严格区分它们的区别) 接着CPU会唤醒内核,又它调度TCP/IP协议栈驱动处理收到的数据包,当解封装后,发现是一个 通知内核数据准备完成,接着内核将数据copy到Nginx的进程内存空间(注:Nginx默认采用epoll,信号驱动I/O 全部挂起,并立即检测网卡上是否有DMA芯片,若有就直接发送指令告诉DMA芯片,你将数据流复制到指定的DMA_ZONE的 可以看到IO的两个阶段,进程都是非阻塞的。 Linux 内核提供了AIO库函数的实现,但是用的很少。目前有很多开源 总而言之,常规文件操作需要从磁盘到页缓存再到用户主存的两次数据拷贝。而mmap操控文件,只需要 直到数据拷贝完成,然后,内核进入睡眠,CPU再将httpd子进程调度到CPU上执行,若时间片用完,则再将其调度到内存 send buffer中,此时httpd子进程被挂起,内核开始将进程内存空间中的数据拷贝到内核内存空间中的send buffer中,准备 当httpd进程被启动后,它通过读取配置文件,获取到要监听的地址和端口,完成socket和bind后,就进入到listen函数了, 睡眠,否则就继续让httpd子进程执行,假如此时时间片没有耗尽,httpd子进程将会再次发起系统调用,让内核将kernel buffer 的进程调度到CPU上执行,当Client收到Server的响应后,回应了ACK报文,Server的网卡收到后,又会继续上面的动作,CPU socket状态为可读时,它将立即解除阻塞,并调用accept()系统调用,此时内核再次被唤醒,然后根据accept的要求,将 然后,内核进入睡眠,CPU将httpd调入CPU上执行,此时select开始遍历获取到的socket set集合,当找到自己监听的 2.当前httpd, Nginx等Web服务器都已经有更先进的技术,如sendfile,mmap,这些机制,可让上面繁琐 ACK报文,并且数据段大小为0,这时内核会去检查未完成连接队列,若找到与该ClientInfo(客户端信息)一致的连接信息,则 即是否变为可读,可写,异常; 若非就绪态,就继续过会儿在检查,这期间httpd将处于阻塞状态的,直到httpd所分配的CPU时间片 非常感谢!同时也非常感谢认真的学习道友骏马金龙,让我能将积累的知识连贯起来,用最简单的语言尽最大 是1500字节,只要超过就会被网络设备切片后,重新封装再发生,但前提是IP包中允许分片 Client和Server之间协商出来的,因为Server或Client都可能因为某些原因接收不了很多数据,因此为了 中查找是否有需要的已打开文件,若无),则会通过已经建立好的映射关系,只使用一次数据拷贝,就从磁盘 接着内核进入睡眠,CPU检查被挂起的进程的时间片是否耗尽,没有就将其调度到CPU上继续执行,否则继续将其它用户空间 将该连接从未完成连接列表中删除,然后在已完成连接队列中插入该连接信息,并标记状态为ESTABLISHED,接着将内核中 则认为通信完成,等待Client后续的请求,若长连接超时,Client没有再次发起请求,则Server将 这个ACK包确认的一定是第二个包,因为第一个包的ACK seq应该是13,而不是17. 网络地址,SOCK_STREAM,是指定socket接受数据格式,共有两种,一种是stream(流,),另一种是dgram(数据报),最后 下面这部分代码是我从网上摘录的,仅为方便理解socket,bind,listen和select


Copyright © 49cc彩票平台-49cc彩票官网 版权所有.

备案号:Copyright © 2002-2017 DEDECMS. 织梦科技 版权所有 Tag标签网站地图 家电维修|北京赛车pk10
北京赛车pk10网址 600w彩票官网 快乐赛车信誉网站 江苏11选5 北京pk赛车网站 抖音彩票 uu彩票平台 澳客彩票网 博猫彩票平台 金沙彩票中心