热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

收发数据的原理(上)

前言:网络知识非常的重要,如果你不是做程序的,那么一些网络常识还是得知道的;而做程序的,就更不用说了,不仅需要

  前言:网络知识非常的重要,如果你不是做程序的,那么一些网络常识还是得知道的;而做程序的,就更不用说了,不仅需要了解一些网络知识,还是知道其原理,如果不了解原理,不敢说他不是程序员,但是总缺了点意思,就像去北京没去过长城一样。

  上一篇讲了网络连接的大概流程,并且文末讲到客户端委托协议栈收发数据可以总结为四步:

  1、创建套接字(创建套接字阶段)

  2、将管道连接到服务器端的套接字上(连接阶段)

  3、收发数据(通信阶段)

  4、断开管道并删除套接字(断开阶段)

  本文会对前两个步骤展开描述,后面两个步骤,下一篇文章介绍,敬请关注!由于网络知识点非常繁杂,读者请沉住气阅读此文,我尽可能详细介绍,尽可能的不那么枯燥,所以本文介绍也有侧重点。读完本文,你可能会对一些知识恍然大悟,哦,原来是这样啊!好了,废话不多说,直接进入主题。

  创造套接字

  协议栈的内部结构

  

image.png

 

  上面是协议栈的内部结构。分为接个部分。上面部分会向下面的部分委派工作。

  应用程序的下面是Socket库,其中包括解析器,解析器向DNS服务器发出查询,它的工作过程我们在上一篇已经介绍过了。

  再下面就是操作系统内部了,其中包括协议栈。协议栈的上半部分有两块,分别是负责用TCP协议收发数据的部分和负责用UDP协议收发数据的部分,它们会接受应用程序的委托执行收发数据的操作。关于TCP和UDP,会在后面文章讲解,目前只要知道像浏览器、邮件等一般的应用程序、QQ文件传输都是使用TCP收发数据的,而像DNS查询、QQ语音 、QQ视频等收发较短的控制数据的时候则使用UDP。

  协议栈的下半部分是利用IP协议控制网络包收发数据的部分,在互联网中发送数据,需要将数据分成一个个小的网络包,然后将网络包发送给通信对象就是由IP负责的。另外,ICMP用于错误提示以及各种控制消息,ARP则是用于查询IP相应的以太网MAC地址。现在只需要大概知道这个名词,后面才会细讲。

  IP下面是驱动程序负责控制网卡硬件,最下面的网卡则是负责完成实际的收发操作——对网线中的信号执行发送和接受操作。

  套接字的实体

  实际上套接字并没存在实体,只是一个概念。在协议栈内部有一块存放控制信息的内存空间,用于记录通信操作的控制信息。比如通信对象的IP地址、端口号、通信操作的状态等。所以硬要说套接字是个实体,那就是这些控制信息或者是保存这些控制信息的内存空间。

  协议栈执行操作时需要参阅这些控制信息。来决定下一步该做什么。比如:发送数据时,看看IP地址和端口号;发送数据后,协议栈需要等待对方返回数据的响应信息,但是数据可能会半途丢失。我们不可能一直等待,所以套接字中需要记录是否已经收到或者发送数据了多久,才方便知道是否要重发数据。套接字的控制信息还有很多作用,在此不一一列举了。

  协议栈是根据套接字中记录的控制信息工作的。

  调用Socket库中的组件

  创建套接字时,需要调用Socket库中的socket组件,注意这里,大写的是Socket,小写是库中的一个程序组件。

  应用程序调用socket程序申请创建套接字,而协议栈则根据应用程序的申请执行创建套接字的操作。

  在创建过程中,协议栈会分配一个用于存放套接字所需的内存空间,用于存放记录套接字操作的控制信息。创建套接字时,数据收发操作还没开始,所以把这初始状态的信息存入内存空间中。到此,创建套接字操作完成。

  创建套接字,不仅要分配空间,而且需要初始化状态信息。

  然后,套接字需要将它的描述符告诉应用程序。描述符相当于车库号,告诉我车库号,我才知道哪个才是我要的车库。同样,描述符是用在应用程序委托协议栈收发数据的时候。套接字包含了通信对象的信息,比如已经说过的IP地址、端口号,所以应用程序收到套接字的描述符,应用程序再提供给协议栈,协议栈就知道了套接字中所包含的通信对象信息,就可以准备连接通信对象了。

  连接服务器

  关于连接

  因为历史原因,其实这里的“连接”就更像是通信前的准备,叫“准备”其实更适合

  调用socket程序申请创建完套接字,然后应用程序会调用Socket库的另外一个程序组件connect,这样协议栈就会将本地的套接字与服务器的套接字进行连接。这里的连接是指通信双方交换控制信息,在套接字记录一些必要信息并准备数据收发的一连串操作。

  我们说的连接不是指网线一直插着的连接,不是指通信过程中将数据转换成电信号。而是当应用程序委托发送数据时,协议栈通过描述符找到的套接字取得通信对象的IP地址和端口号等信息。这属于连接操作的目的之一。

  说完应用程序,再说下服务器那边,服务器也会创建套接字,但是服务器的协议栈和客户端这边一样,没有类似一个描述符的东西就没办法知道通信对象,没法开始通信。所以得有客户端先开始请求,告诉服务器必要信息。比如“我要和你请求,我的IP地址是10.10.1.118,端口号是8900”。所以,应用程序向服务器发送请求,也是连接操作的目的之一。

  连接实际上通信双方交换控制信息,在套接字中记录必要信息并准备数据收发的一连串操作。

  控制信息,是控制数据收发操作的一些信息。IP地址、端口号就属于其中的信息。其余的控制信息,我们后面再介绍。双方通过通信规则进行信息交换从而完成数据收发准备。收发操作,需要一块临时存放要收发的数据的内存空间,这块内存空间叫做缓冲区,它是在连接操作过程中分配的。

  关于控制信息头部

  控制信息可以分为两类。一是客户端和服务器相互联络时交换的控制信息。二是保存在套接字中,用来控制协议栈操作的信息。

  第一类:客户端和服务器交换的控制信息,不仅是在连接时需要,包括数据收发和断开连接操作在内,整个通信过程都需要。我们前面说过,数据会被分成一个个网络包发送,而这些信息就是被添加在客户端与服务器传递的网络包的开头。在连接阶段,由于数据收发还没有开始,网络包中没有实际数据,只有控制信息。这些控制信息位于网络包的开头,因此成为头部。当然,以太网和IP协议也有自己的头部(包含着控制信息),为了避免不同头部混淆,我们一般记作TCP头部,以太网头部、IP头部。本文主要讲解TCP头部,其余知识后面再讲,读者有兴趣可先自行查阅。

  客户端和服务器在通信中会将必要的信息存放在头部并相互确认。大家现在要知道的就是头部是用来记录和交换控制信息的。

  第二类:套接字中的控制信息。这里会保存应用程序传递来的信息以及从通信对象接收到的信息,还有收发数据操作的执行状态等信息也会保存于此,协议栈根据这些信息来执行每一步操作。

  通信操作中使用的控制信息分为两类:

  (1)头部中的信息

  (2)套接字(协议栈的内存空间)中记录的信息

  连接操作的实际过程

  上面我们已经介绍了连接(准备)操作的含义,接下来看一下具体操作过程。首先是应用程序调用Socket库中的connect,类似下面

  connect (描述符,服务器IP地址,服务器端口号,…)

  上面的调用提供了服务器的IP地址和端口号,这些信息会传递给协议栈中的TCP模块。TCP模块就会与该IP地址对应的对象,也就是与服务器的TCP模块交换控制信息。

  

tcp-header

 

  seq:(Sequence Number):本报文段数据的第一个字节的序号

  ack:(Acknowledgment Number):确认号——期望收到对方下个报文段的第一个数据字节的序号

  控制位包含以下几部分

  URG:紧急指针有效位。

  SYN:建立连接,当需要建立连接时,他的值为1.即SYN=1

  ACK:确认连接,当ACK=1是才有效,ACK=0是此控制位无效。

  FIN:断开连接,提出断开连接这一方的值为1.

  RST:重新建立连接,值为1时代表重新建立连接。

  PSH:要求接收方将数据尽快将数据段送达应用层

  上图主要介绍了TCP头部。其中TCP头部目前要认知的有发送方和接收方的端口号,序号(seq)是发送方告诉接收方本报文段数据的第一个字节的序号,ack号是接收方告诉发送方已收到了所有数据的第几个字节。其中ack是Acknowledgment Number的缩写。可能读者纳闷IP地址在哪,IP地址其实在IP头部才有。由于本文重点是介绍TCP,所以下方只给出IP头部图,读者自行阅读

  

ip-header

 

  应用程序与服务器的TCP模块交换控制信息这一过程包含几个步骤:首先,客户端先创建一个包含表示开始数据收发操作的控制信息的头部(上面所说网络包中开头的控制信息),头部包含很多字段,其中要关注的重点是客户端和服务器的端口号,也就是说,客户端的套接字知道了连接服务器的哪个套接字。然后,我们把头部中的控制位的SYN设置为1,大家可以认为它表示连接。此外,还需设置适当的序号和窗口大小。

  连接操作的第一步是在TCP模块处创建表示连接控制信息的头部

  通过TCP头部中的发送方和接收方的端口号可以找到要连接的套接字

  当TCP头部创建好之后,接下来TCP模块会将信息传给IP模块并委托它进行发送。IP模块执行网络包发送操作后,网络包就会通过网络发送到服务器的IP模块,再由服务器的IP模块把接收到的数据传给服务器自身的TCP模块,这时,服务器的TCP模块会根据TCP头部的信息找到端口号对应的套接字,然后套接字就会写入相应的信息,并把状态改成正在连接。

  TCP模块、IP模块分别属于网络原理中OSI模型7层结构的传输层、网络层,而传输层处于网络层的上一层,也就是高一层,要完成传送数据,必须从通信一方的高层传到低层,再通过网络传给通信另外一方的低层,再到那一方的高层完成接收。所以发送数据得从高一层的TCP到低层的IP模块逐一传递。

  上述操作完成后,服务器的TCP模块会返回响应,这个过程跟客户端发送数据给服务端一样,需要在TCP头部中设置发送方和接收方端口以及SYN比特。另外,客户端向服务器发送第一个网络包时,由于服务器还没有接受过网络包,所以ACK比特设为0,那么在返回响应就需要将ACK控制位设为1,表示已经收到相应的网络包。网络中经常发生错误,网络包也会丢失。因此通信双方必须相互确认网络包是否已经送达,通信双方如何确认?其实就是通过设置ACK。接下来,服务器TCP模块会将TCP头部传给IP模块,并委托IP模块向客户端返回响应。

  然后,网络包就会返回客户端,通过IP模块到达TCP模块,并通过TCP头部信息确认连接服务器的操作是否成功。如果SYN为1,则表示连接成功,这时会向套接字中写入服务器的IP地址、端口号等信息,同时还会将状态改成连接完毕。到这里,客户端的操作就已经完成。但其实还剩下一个步骤,客户端收到数据后,也要像服务器那样把把ACK设置为1,并发回给服务器,告诉服务器,我已经收到服务器发来的响应包,当服务器收到这个返回包后,连接操作才算全部完成。

  有没有觉得上面的双方相互确认网络包操作,似乎很熟悉,没错!它其实就是tcp的三次握手。

  TCP三次握手

  1.A向B发起建立连接请求:

  2.B收到A的发送信号,并且向A发送确认信息

  3.A收到B的确认信号,并且向B发送确认信号

  连接(准备)操作完成后,套接字可以随时进行收发数据了,这个时候我们可以理解通信双方已经有一条相连的管道,这条管道连接着双方的套接字。当然这条管道并不真正存在,只是业界为了方便理解,比喻而已。

  建立连接后,协议栈的连接操作就结束了。也就是说,当初应用程序调用Socket库中connect程序组件操作已经执行完毕,控制流程又重新交回到客户端。等到后面的收发数据操作。

  在此,收发数据的创建套接字阶段、连接阶段已经讲完,剩下的通信阶段、断开阶段留到下次再讲。网络的东西很枯燥,并且并不是那么可视化,学会的要诀是沉住气,看到这里,如果你现在还不能讲到收发数据的前两个步骤,请回到文章顶部,再看一遍。Over and over again,你就会学有所成。

  


推荐阅读
  • 在JavaWeb项目架构中,NFS(网络文件系统)的实现与优化是关键环节。NFS允许不同主机系统通过局域网共享文件和目录,提高资源利用率和数据访问效率。本文详细探讨了NFS在JavaWeb项目中的应用,包括配置、性能优化及常见问题的解决方案,旨在为开发者提供实用的技术参考。 ... [详细]
  • TCP三次握手过程详解与图示解析
    本文详细解析了TCP三次握手的过程,并通过图示清晰展示了各个状态的变化。同时,文章还介绍了四次挥手的图解,解释了在TIME_WAIT状态中,客户端最后一次发送的ACK包的作用和重要性。 ... [详细]
  • 西北工业大学作为陕西省三所985和211高校之一,虽然在农业和林业领域不如某些顶尖院校,但在航空航天领域的实力尤为突出。该校的计算机科学专业在科研和教学方面也具有显著优势,是考研的理想选择。 ... [详细]
  • Python 数据可视化实战指南
    本文详细介绍如何使用 Python 进行数据可视化,涵盖从环境搭建到具体实例的全过程。 ... [详细]
  • 网站访问全流程解析
    本文详细介绍了从用户在浏览器中输入一个域名(如www.yy.com)到页面完全展示的整个过程,包括DNS解析、TCP连接、请求响应等多个步骤。 ... [详细]
  • 对于希望在未越狱的iOS设备上修改Hosts文件的苹果用户来说,了解文件的具体位置和操作步骤至关重要。本文将详细介绍如何通过安装最新版本的iTunes来实现这一目标,并提供实用的操作指南,帮助用户轻松完成Hosts文件的编辑。 ... [详细]
  • MySQL数据库安装图文教程
    本文详细介绍了MySQL数据库的安装步骤。首先,用户需要打开已下载的MySQL安装文件,例如 `mysql-5.5.40-win32.msi`,并双击运行。接下来,在安装向导中选择安装类型,通常推荐选择“典型”安装选项,以确保大多数常用功能都能被正确安装。此外,文章还提供了详细的图文说明,帮助用户顺利完成整个安装过程,确保数据库系统能够稳定运行。 ... [详细]
  • Linux入门教程第七课:基础命令与操作详解
    在本课程中,我们将深入探讨 Linux 系统中的基础命令与操作,重点讲解网络配置的相关知识。首先,我们会介绍 IP 地址的概念及其在网络协议中的作用,特别是 IPv4(Internet Protocol Version 4)的具体应用和配置方法。通过实际操作和示例,帮助初学者更好地理解和掌握这些基本技能。 ... [详细]
  • 2016-2017学年《网络安全实战》第三次作业
    2016-2017学年《网络安全实战》第三次作业总结了教材中关于网络信息收集技术的内容。本章主要探讨了网络踩点、网络扫描和网络查点三个关键步骤。其中,网络踩点旨在通过公开渠道收集目标信息,为后续的安全测试奠定基础,而不涉及实际的入侵行为。 ... [详细]
  • 基于域名、端口和IP的虚拟主机构建方案
    本文探讨了在单台物理服务器上构建多个Web站点的虚拟主机方案,详细介绍了三种主要的虚拟主机类型:基于域名、基于IP地址和基于端口的虚拟主机。每种类型的实现方式及其优缺点均进行了深入分析,为实际应用提供了全面的技术指导。 ... [详细]
  • 公司计划部署邮件服务器,考虑到已有域名,决定自行搭建内部邮件服务器。经过综合考量,最终选择在Linux环境中进行搭建,并记录了相关配置和实践过程。本文将详细介绍Postfix的基本设置步骤和实践经验,帮助读者快速掌握邮件服务器的搭建方法。 ... [详细]
  • 解决118错误代码:专业指南与常见解决方案
    解决118错误代码:专业指南与常见解决方案 ... [详细]
  • 负载均衡基础概念与技术解析
    随着互联网应用的不断扩展,用户流量激增,业务复杂度显著提升,单一服务器已难以应对日益增长的负载需求。负载均衡技术应运而生,通过将请求合理分配到多个服务器,有效提高系统的可用性和响应速度。本文将深入探讨负载均衡的基本概念和技术原理,分析其在现代互联网架构中的重要性及应用场景。 ... [详细]
  • MySQL性能优化与调参指南【数据库管理】
    本文详细探讨了MySQL数据库的性能优化与参数调整技巧,旨在帮助数据库管理员和开发人员提升系统的运行效率。内容涵盖索引优化、查询优化、配置参数调整等方面,结合实际案例进行深入分析,提供实用的操作建议。此外,还介绍了常见的性能监控工具和方法,助力读者全面掌握MySQL性能优化的核心技能。 ... [详细]
  • 深入解析OSI七层架构与TCP/IP协议体系
    本文详细探讨了OSI七层模型(Open System Interconnection,开放系统互连)及其与TCP/IP协议体系的关系。OSI模型将网络通信过程划分为七个层次,每个层次负责不同的功能,从物理层到应用层逐步实现数据传输和处理。通过对比分析,本文揭示了OSI模型与TCP/IP协议在结构和功能上的异同,为理解现代网络通信提供了全面的视角。 ... [详细]
author-avatar
书友49916066
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有