linux高性能服务器开发之TCP/IP协议族(1)

2023-11-07

TCP/IP协议族体系结构以及主要协议

在这里插入图片描述
每层协议完成不一样的功能,上层协议得借助下层协议提供的服务(计网)

数据链物层

数据链物层实现网卡接口的网络驱动程序,网络驱动程序隐藏一些(物理层不同电气特性),为上层提供一个统一的接口。
常用的协议ARR(地址解析协议)和RARR(逆地址解析协议),实现IP地址与MAC地址互换。(RARR)仅适用无法记住IP地址,可以用MAC来查询自己的IP地址。

网络层

网络层实现数据包的选路以及转发
WAN通常使用分级的路由器(不同路线)连接分散的主机或LAN,隐藏网络拓扑连接的细节,提供一种直接连接的观点。
IP协议通过hop by hop 的方式来确定通信路径
ICMP检测网络连接.(IP提供服务)
在这里插入图片描述
8位类型字段用于区分报文类型。它将ICMP报文分为两大类:一类是差错报文,这类报文主要用来回应网络错误,比如目标不可到达(类型值为3)和重定向(类型值为5)﹔另一类是查询报文,这类报文用来查询网络信息,比如ping程序就是使用ICMP报文查看目标是否可到达(类型值为8)的。有的ICMP报文还使用8位代码字段来进一步细分不同的条件。比如重定向报文使用代码值О表示对网络重定向,代码值1表示对主机定向。ICMP报文使用16位校验和字段对整个报文(包括头部和内容部分)进行循环冗余校验(Cvclic Redundancv Check,CRC),以检验报文在传输讨程中是丕揭坏。

传输层

传输层实现end to end 的通信 不在乎数据包的中转,下图网络层与其展现区别
在这里插入图片描述

总结就是:
   数据链物层:封装物理层的电气细节
   网络层:封装网络连接的细节
   传输层:封装一条end to end 的逻辑通信链路

TCP协议(Transmission Control Protocol,传输控制协议)为应用层提供可靠的、面向连接的和基于流(stream)的服务。TCP协议使用超时重传、数据确认等方式来确保数据包被正确地发送至目的端,因此TCP服务是可靠的。使用TCP协议通信的双方必须先建立TCP连接,并在内核中为该连接维持一些必要的数据结构,比如连接的状态、读写缓冲区,以及诸多定时器等。当通信结束时,双方必须关闭连接以释放这些内核数据。TCP服务是基于流的。基于流的数据没有边界(长度)限制,它源源不断地从通信的一端流入另一端。发送端可以逐个字节地向数据流中写人数据,接收端也可以逐个字节地将它们读出。
UDP协议(User Datagram Protocol,用户数据报协议)则与TCP协议完全相反,它为应用层提供不可靠、无连接和基于数据报的服务。“不可靠”意味着UDP协议无法保证数据从发送端正确地传送到目的端。如果数据在中途丢失,或者目的端通过数据校验发现数据错误而将其丢弃,则UDP协议只是简单地通知应用程序发送失败。因此,使用UDP协议的应用程序通常要自己处理数据确认、超时重传等逻辑UDP协议是无连接的,即通信双方不保持一个长久的联系,因此应用程序每次发送数据都要明确指定接收端的地址(IP地址等信息)。基于数据报的服务,是相对基于流的服务而言的。每个UDP数据报都有一个长度,接收端必须以该长度为最小单位将其所有内容一次性读出,否则数据将被截断。

应用层

应用层:在用户空间实现,因为它负责处理众多逻辑,比如文件传输、名称查询和网络管理等。如果应用层也在内核中实现,则会使内核变得非常庞大。当然,也有少数服务器程序是在内核中实现的,这样代码就无须在用户空间和内核空间来回切换(主要是数据的复制),极大地提高了工作效率。不过这种代码实现起来较复杂,不够灵活,且不便于移植。本书只讨论用户空间的网络编程。
ping是应用程序,而不是协议,前面说过它利用ICMP报文检测网络连接,是调试网络环境的必备工具。
telnet 协议是一种远程登录协议,它使我们能在本地完成远程任务,本书后续章节将会多次使用telnet客户端登录到其他服务上。
OSPF (Open Shortest Path First,开放最短路径优先〉协议是一种动态路由更新协议,用于路由器之间的通信,以告知对方各自的路由信息。
DNS ( Domain Name Service,域名服务)协议提供机器域名到IP地址的转换,我们将在后面简要介绍 DNS协议。
应用层协议(或程序)可能跳过传输层直接使用网络层提供的服务,比如 ping 程序和OSPF 协议。应用层协议(或程序)通常既可以使用TCP服务,又可以使用UDP服务,比如DNS协议。我们可以通过letc/services文件查看所有知名的应用层协议,以及它们都能使那些传输层服务

封装

上层协议是如何使用下层协议提供的服务的呢?

其实这是通过**封装(**encapsulation)实现的。应用程序数据在发送到物理网络上之前,将沿着协议栈从上往下依次传递。每层协议都将在上层数据的基础上加上自己的头部信息(有时还包括尾部信息),以实现该层的功能,这个过程就称为封装

在这里插入图片描述
经过TCP封装后的数据称为TCP报文段(TCP message segment),或者简称TCP段。前文提到,TCP协议为通信双方维持一个连接,并且在内核中存储相关数据。这部分数据中的TCP头部信息和TCP内核缓冲区(发送缓冲区或接收缓冲区)数据一起构成了TCP报文段
在这里插入图片描述
当发送端应用程序使用send(或者write)函数向一个TCP连接写人数据时,内核中的TCP模块首先把这些数据复制到与该连接对应的TCP内核发送缓冲区中,然后TCP模块调用IP模块提供的服务,传递的参数包括TCP头部信息和TCP发送缓冲区中的数据,即TCP报文段。
经过UDP封装后的数据称为UDP数据报(UDP datagram)。UDP对应用程序数据的封装与TCP类似。不同的是,UDP无须为应用层数据保存副本,因为它提供的服务是不可靠的。当一个UDP数据报被成功发送之后,UDP内核缓冲区中的该数据报就被丢弃了。如果应用程序检测到该数据报未能被接收端正确接收,并打算重发这个数据报,则应用程序需要重新从用户空间将该数据报拷贝到UDP内核发送缓冲区中。
经过数据链路层封装的数据称为帧(frame)。传输媒介不同,帧的类型也不同。比如,以太网上传输的是以太网帧( ethernet frame),而令牌环网络上传输的则是令牌环帧( token ring frame)

以太网

分用

当帧到达目的主机时,将沿着协议栈自底向上依次传递.各层协议依次处理帧中本层负责的头部数据,以获取所需的信息,并最终将处理后的帧交给目标应用程序.这个过程称为分用(解复用)。
在这里插入图片描述
因为lP协议、ARP协议和RARP协议都使用帧传输数据,所以帧的头部需要提供某个字段(具体情况取决于帧的类型)来区分它们。以以太网帧为例,它使用2字节的类型字段来标识上层协议(见图1-6)。如果主机接收到的以太网帧类型字段的值为Ox800,则帧的数据部分为IP数据报(见图1-4),以太网驱动程序就将帧交付给IP模块﹔若类型字段的值为0x806,则帧的数据部分为ARP请求或应答报文,以太网驱动程序就将帧交付给ARP模块;若类型字段的值为0x835,则帧的数据部分为RARP请求或应答报文,以太网驱动程序就将帧交付给RARP模块。

同样,因为ICMP协议、TCP协议和UDP协议都使用IP协议,所以IP数据报的头部采用16位的协议( protocol)字段来区分它们。

TCP报文段和UDP数据报则通过其头部中的16位的端口号(port number)字段来区分上层应用程序。比如 DNS协议对应的端口号是53,HTTP协议(Hyper-Text TransfetProtocol,超文本传送协议)对应的端口号是80。所有知名应用层协议使用的端口号都可在/etc/services文件中找到。

测试网络

该测试网络主要用于分析ARP协议、IP协议、ICMP协议、TCP协议和 DNS协议。我们通过抓取该网络上的以太网帧,查看其中的以太网帧头部、IP数据报头部、TCP报文段头部信息,以获取网络通信的细节。这样,以理论结合实践,我们就清楚TCP/IP通信具体是
在这里插入图片描述

ARP

ARP协议能实现任意网络层地址任意物理地址的转换
工作原理是:主机向自己所在的网络广播一个ARP请求,该请求包含目标机器的网络地址。此网络上的其他机器都将收到这个请求,但只有被请求的目标机器会回应一个ARP应答,其中包含自己的物理地址。

以太网请求APR报文

硬件类型字段定义物理地址的类型,它的值为1表示MAC地址
协议类型字段表示要映射的协议地址类型,它的值为0x800,表示IP地址。
硬件地址长度字段和协议地址长度字段,顾名思义,其单位是字节。对MAC地址来说,其长度为6;对IP(v4)地址来说,其长度为4。
**操作字段指出4种操作类型:**ARP请求(值为1)、ARP应答(值为2)、RARP请求(值为3)和RARP应答(值为4)。
最后4个字段指定通信双方的以太网地址和IP地址。发送端填充除目的端以太网地址外的其他3个字段,以构建ARP请求并发送之。接收端发现该请求的目的端IP地址是自己,就把自己的以太网地址填进去,然后交换两个目的端地址和两个发送端地址,以构建ARP应答并返回之(当然,如前所述,操作字段需要设置为2).

通常,ARP维护一个高速缓存,其中包含经常访问(比如网关地址)或最近访问的机器的IP地址到物理地址的映射。这样就避免了重复的ARP请求,提高了发送数据包的速度。

[root@localhost ~]# arp
Address                  HWtype  HWaddress           Flags Mask            Iface
192.168.179.254          ether   00:50:56:f1:e3:72   C                     ens33
gateway                  ether   00:50:56:f7:71:f5   C                     ens33
[root@localhost ~]# arp -a
? (192.168.179.254) at 00:50:56:f1:e3:72 [ether] on ens33
gateway (192.168.179.2) at 00:50:56:f7:71:f5 [ether] on ens33
[root@localhost ~]# 
//第一项是ip 地址
//第二项是路由器的MAC

DNS工作原理

DNS是一套分布式的域名服务系统。每个DNS 服务器上都存放着大量的机器名和IP地址的映射,并且是动态更新的。众多网络客户端程序都使用DNS协议来向DNS服务器查询目标主机的P地址。DNS查询和应答报文的格式如图所示:

在这里插入图片描述
16位标识字段用于标记一对DNS查询和应答,以此区分一个DNS应答是哪个DNS查询的回应。

16位标志字段用于协商具体的通信方式和反馈通信状态。DNS报文头部的16位标志字段的细节如图:
在这里插入图片描述
解析:高性能linux服务器31

[root@localhost ~]# vim /etc/resolv.conf//(DNS服务器的IP地址 )
[root@localhost ~]# host -t A www.baidu.com
//host命令的输出告诉我们,机器名www.baidu.com是www.a.shifen.com.的别名,并且该机器名对应两个IP地址。host命令使用DNS协议和DNS服务器通信,其一t选项告诉DNS 协议使用哪种查询类型。我们这里使用的是A类型,即通过机器的域名获得其ⅣP地址(但实际上返回的资源记录中还包含机器的别名)
www.baidu.com is an alias for www.a.shifen.com.
www.a.shifen.com has address 14.215.177.39
www.a.shifen.com has address 14.215.177.38

socket

前文提到,数据链路层、网络层、传输层协议是在内核中实现的。因此操作系统需要实现一组系统调用,使得应用程序能够访问这些协议提供的服务。实现这组系统调用的API( Application Programming Interface,应用程序编程接口)
由socket定义的这一组API提供如下两点功能:
一是将应用程序数据从用户缓冲区中复制到TCP/UDP内核发送缓冲区,以交付内核来发送数据(比如图1-5所示的send函数),或者是从内核TCP/UDP接收缓冲区中复制数据到用户缓冲区,以读取数据﹔
二是应用程序可以通过它们来修改内核中各层协议的某些头部信息或其他数据结构,从而精细地控制底层通信的行为。比如可以通过setsockopt 函数来设置IP数据报在网络上的存活时间。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

linux高性能服务器开发之TCP/IP协议族(1) 的相关文章

  • Linux下的C#,Process.Start()异常“没有这样的文件或目录”

    我在使用 Process 类调用程序来启动程序时遇到问题 可执行文件的层次结构位于 bin 目录下 而当前工作目录需要位于 lib 目录下 project bin a out this is what I need to call lib
  • 从 Linux 命令行发送 SNMP 陷阱消息

    Folks 我需要从 Linux 命令行使用此命令 snmptrap 将自定义消息发送到陷阱侦听器 我需要根据用户设置在 v1 和 v2c 中发送相同的消息 这是我发现的 For v1 snmptrap v 1 c Tas hostname
  • 为什么使用Python的os模块方法而不是直接执行shell命令?

    我试图了解使用Python的库函数执行特定于操作系统的任务 例如创建文件 目录 更改文件属性等 背后的动机是什么 而不是仅仅通过执行这些命令os system or subprocess call 例如 我为什么要使用os chmod而不是
  • jpackage linux 创建的桌面文件不足

    我刚刚开始使用 jpackage 它是一个非常棒的工具 只要迈出一步 我的肩上的工作就减轻了很多 我对看起来硬编码且无法定制的东西越感到惊讶 JPackage 自动生成启动器 lib
  • 测试linux下磁盘空间不足

    我有一个程序 当写入某个文件的磁盘空间不足时 该程序可能会死掉 我不确定是否是这种情况 我想运行它并查看 但我的测试服务器不会很快耗尽空间 有什么办法可以嘲笑这种行为吗 看起来没有任何方法可以在 Ubuntu 中设置文件夹 文件大小限制 并
  • Linux TCP服务器:在接受连接之前读取客户端的IP地址

    Related C Winsock API如何在接受连接之前获取连接客户端IP https stackoverflow com questions 716209 c winsock api how to get connecting cli
  • 退出 bash 脚本但保持进程运行

    我正在运行服务器 需要使用参数执行以下命令 这些脚本目前工作得很好 但问题是当我运行脚本时我无法返回到控制台 它在控制台中保持运行 如果我强行停止它 那么该过程也会停止 我想继续运行该进程并返回到控制台 bin sh php home st
  • 静态链接共享对象?或者损坏的文件?

    我有一个从专有来源获得的库 我正在尝试链接它 但出现以下错误 libxxx so 文件无法识别 文件格式无法识别 Collect2 ld 返回 1 退出状态 确实 ldd libxxx so statically linked 这究竟意味着
  • 在中断时获取 current->pid

    我正在Linux调度程序上写一些东西 我需要知道在我的中断到来之前哪个进程正在运行 当前的结构可用吗 如果我在中断处理程序中执行 current gt pid 我是否可以获得我中断的进程的 pid 你可以 current gt pid存在并
  • 通过 SSH 将变量传递给远程脚本

    我正在通过 SSH 从本地服务器在远程服务器上运行脚本 首先使用 SCP 复制该脚本 然后在传递一些参数时调用该脚本 如下所示 scp path to script server example org another path ssh s
  • 编写多个mysql脚本

    是否可以在复合脚本中包含其他 mysql 脚本 理想情况下 我不想为包含的脚本创建存储过程 对于较大的项目 我想分层维护几个较小的脚本 然后根据需要组合它们 但现在 我很乐意学习如何包含其他脚本 source是一个内置命令 您可以在 MyS
  • gdb 错误 - 文件不是可执行格式:无法识别文件格式

    我正在尝试使用 gdb 调试某个名为 xdf 的程序 但是当我运行 gdb xdf 时 出现以下错误 home nealtitusthomas X ray astronomy heasoft 6 24 x86 64 pc linux gnu
  • 远程linux服务器到远程linux服务器大型稀疏文件复制 - 如何?

    我有两台 CentOS 5 4 服务器 每台服务器上都安装了 VMware Server 假设我始终对 vmware 虚拟机使用稀疏文件 将虚拟机文件从一台服务器复制到另一台服务器的最可靠 最快速的方法是什么 虚拟机的文件复制起来很痛苦 因
  • 如何仅将整个嵌套目录中的头文件复制到另一个目录,在复制到新文件夹后保持相同的层次结构

    我有一个目录 其中有很多头文件 h 和其他 o 和 c 文件以及其他文件 这个目录里面有很多嵌套的目录 我只想将头文件复制到一个单独的目录 并在新目录中保留相同的结构 cp rf oldDirectory newDirectory将复制所有
  • Windows 与 Linux 文本文件读取

    问题是 我最近从 Windows 切换到 Ubuntu 我的一些用于分析数据文件的 python 脚本给了我错误 我不确定如何正确解决 我当前仪器的数据文件输出如下 Header 有关仪器等的各种信息 Data 状态 代码 温度 字段等 0
  • 是否从页面缓存中的脏页面进行文件读取?

    当字节写入文件时 内核不会立即将这些字节写入磁盘 而是将这些字节存储在页缓存中的脏页中 回写缓存 问题是 如果在脏页刷新到磁盘之前发出文件读取 则将从缓存中的脏页提供字节 还是首先将脏页刷新到磁盘 然后进行磁盘读取以提供字节 将它们存储在进
  • 进程名称长度的最大允许限制是多少?

    进程名称允许的最大长度是多少 我正在读取进程名称 proc pid stat文件 我想知道我需要的最大缓冲区 我很确定有一个可配置的限制 但就是找不到它在哪里 根据man 2 prctl http man7 org linux man pa
  • 如何确保 numpy BLAS 库可用作动态加载库?

    The theano安装文档 http www deeplearning net software theano install html troubleshooting make sure you have a blas library指
  • 确保 config.h 包含一次

    我有一个库项目 正在使用 Linux 中的 autotools 套件移植到该项目 我对自动工具很陌生 本周 我已经了解了其操作的基础知识 我有一个关于如何保留内容的问题config h免遭重新定义 我惊讶地发现生成的config h文件也没
  • 套接字:监听积压并接受

    listen sock backlog 在我看来 参数backlog限制连接数量 这是我的测试代码 server initialize the sockaddr of server server sin family AF INET ser

随机推荐

  • linux 根目录各目录功能简介

    CentOS 6 5 目录 说明 备注 bin 存放普通用户可执行的指令 即使在单用户模式下也能够执行处理 boot 开机引导目录 包括Linux内核文件与开机所需要的文件 dev 设备目录 所有的硬件设备及周边均放置在这个设备目录中 et
  • Docker Compose 笔记 网络

    Compose 简介 1 引入 通过前面的知识 我们知道使用一个 Dockerfile 模板文件 可以让用户很方便的定义一个单独的应用容器 从而得到一个镜像 然而 在日常工作中 经常会碰到需要多个容器相互配合来完成某项任务的情况 例如要实现
  • xss挑战1-10关

    level1 没有任何过滤 直接URL后面加XSS测试语句 弹窗 level2 有搜索框 像第一关一样在搜索框测试一下 但是没有像第一关一样弹窗 查看源码发现我们的XSS语句被赋值给value并且在input标签里 所以我们需要闭合valu
  • Acwing-4644. 求和

    暴力解法 TLE了hh include
  • git入门教程

    文章目录 Git教程 创建版本库 把文件添加到版本库 查看文件状态 版本回退 工作区和暂存区 管理 撤销修改 删除文件 Git远程仓库 Git教程 Git是目前世界上最先进的分布式版本控制系统 Git用C语言开发 Linus一直痛恨的CVS
  • Midjourney关键字--兔子类

    1 A lovely and happy Pixar style rabbit baby wearing a checked shirt carrying a schoolbag to school with a sweet smile b
  • zkEVM战局简析:zkSync、StarkNet、Scroll和挑战者们

    不同的项目正在探索不同的方向 这或许是最利于行业的发展模式 原文作者 Grant Griffith 由 Odaily星球日报 Azuma 编译 编者按 10 月 28 日 由 Matter Labs 构建的以太坊扩容解决方案正式发布了 zk
  • JAVA之猜数字游戏

    1 随机生成一个0 99 包括0和99 的数字 从控制台输入猜测的数字 输出提示太大还是太小 继续猜测 直到猜到为止 游戏过程中 记录猜对所需的次数 游戏结束后公布结果 打开记事本 写如下一段代码 import java util Rand
  • SpringBoot2对接线程池

    SpringBoot2对接线程池 1 配置线程池Bean package com itennishy test config import java util concurrent ThreadPoolExecutor import org
  • Qt中extern全局变量的使用

    参考网址 https blog csdn net Soar dream article details 101025153 https blog csdn net weixin 45571586 article details 118109
  • C语言位操作

    C语言位操作 1 位与 按照二进制位一一对应 只有全1才为真 否则为假 特定位置置0用位与 2 位或 按照二进制 有真则真 全假才假 特定位置置1用位或 3 位取反 按照二进制位 1变为0 0变为1 逻辑取反 数当成整体 不变二进制 不是0
  • 错误 Angular2 Can't bind to 'routerLink' since it isn't a known property of 'a'

    Can t bind to routerLink since it isn t a known property of a 解决办法 检查是否没有 import RouterModule import RouterModule from a
  • 阿里java编程规范之异常处理、安全规约、MySql数据库

    注 本文内容整理自 阿里java编码规范 除 编程规约 外的其它规则 异常处理 强制 1 Java类库中可以通过预检查方式规避的 RuntimeException不应该通过catch的方式来处理 如 IndexOutOfBoundsExce
  • LruCache基本使用和原理分析

    最近在研究时区问题时 时区的底层实现涉及到BasicLruCache集合的使用 故而对LruCache做了部分的了解 BasicLruCache 是 Android 提供的一个简单的 LRU 缓存实现 但在标准的 Java 类库中并不存在
  • 基于SpringBoot的校园志愿者管理系统

    末尾获取源码 开发语言 Java Java开发工具 JDK1 8 后端框架 SpringBoot 前端 HTML Vue 数据库 MySQL5 7和Navicat管理工具结合 服务器 Tomcat8 5 开发软件 IDEA Eclipse
  • windows 安装 minio

    windows 安装 minio 1 通过powershell 安装 Invoke WebRequest Uri https dl min io server minio release windows amd64 minio exe Ou
  • 小试一下Google App Engine

    这两天关心了一下云 所以也看到google app engine了 今天小小试了一下 做下记录 主页 登录http code google com intl zh CN appengine 下载 App Engine SDK GoogleA
  • 使用StarRocks导入大数据:详细教程及示例代码

    使用StarRocks导入大数据 详细教程及示例代码 StarRocks是一个快速 可扩展的大数据分析引擎 它提供了高性能的数据导入功能 在本文中 我们将介绍如何使用StarRocks导入大数据 并提供相应的示例代码 步骤1 准备工作 在开
  • 云计算平台常用命令

    云计算IAAS篇 mysql篇 mysql uroot p000000 使用root账号登录mysql use mysql 切换到mysql层 show tables 查询mysql数据库列表 select from mysq
  • linux高性能服务器开发之TCP/IP协议族(1)

    TCP IP协议族体系结构以及主要协议 每层协议完成不一样的功能 上层协议得借助下层协议提供的服务 计网 数据链物层 数据链物层实现网卡接口的网络驱动程序 网络驱动程序隐藏一些 物理层不同电气特性 为上层提供一个统一的接口 常用的协议ARR