《TCP/IP网络编程》学习笔记 | Chapter 3:地址族与数据序列

《TCP/IP网络编程》学习笔记 | Chapter 3:地址族与数据序列

  • 《TCP/IP网络编程》学习笔记 | Chapter 3:地址族与数据序列
    • 分配给套接字的IP地址和端口号
      • 网络地址
      • 网络地址分类和主机地址边界
      • 用于区分套接字的端口号
      • 数据传输过程示例
    • 地址信息的表示
      • 表示IPv4地址的结构体
      • 结构体sockaddr_in的成员分析
        • 成员sin_family
        • 成员sin_port
        • 成员sin_addr
        • 成员sin_zero
    • 网络字节序与地址变换
      • 字节序与网络字节序
      • 字节序转换

《TCP/IP网络编程》学习笔记 | Chapter 3:地址族与数据序列

分配给套接字的IP地址和端口号

IP是为收发网络数据而分配给计算机的值。端口号是为区分程序中创建的套接字而分配给套接字的序号。

网络地址

IP地址有两种表达形式:

  • IPv4:4字节地址族
  • IPv6:16字节地址族

一定要记住IPv4和IPv6不只是在地址长度不同,在其具体的协议实现上是有很大程度的不同的。IPv6出现的主要目的是为了解决由于计算机数量的暴增导致IP地址可能出现不足的问题的,现在IPv6的地址范围可以让地球上任何一个沙子都拥有IP地址。

让我们继续说回到IPv4上,IPv4标准的4字节IP地址分为网络地址和主机(指计算机)地址,且分为A、B、C、D、E等类型。

类型地址范围网络地址位数主机地址位数可分配的网络数量每个网络可分配的主机数量
A1.0.0.0 - 126.255.255.25582412816,777,216
B128.0.0.0 - 191.255.255.255161616,38465,536
C192.0.0.0 - 223.255.255.2552482,097,152256
D224.0.0.0 - 239.255.255.255未分配未分配未分配未分配

网络地址是用来标识一个特定网络的。它告诉路由器和其他网络设备,数据应该被发送到哪个网络。

主机地址是用来标识网络中具体设备的。它必须在网络中是唯一的,以确保数据能够被正确地发送到正确的设备。

现在我来举个例子来具体理解一下网络地址和主机地址的含义。
假设向WWW.SEMI.COM公司传输数据,该公司内部构建了局域网,把所有计算机连接起来。因此,首先应向SEMI.COM网络传输数据,也就是说,并非一开始就浏览所有4字节IP地址,进而找到目标主机;而是仅浏览4字节IP地址的网络地址,先把数据传到SEMI.COM的网络。SEMI.COM网络(构成网络的路由器)接收到数据后,浏览传输数据的主机地址(主机ID)并将数据传给目标计算机。

网络地址分类和主机地址边界

只需通过地址的第一个字节即可判断网络地址占用的字节数,因为我们根据地址的边界区分网络地址,如下所示:

  • A类地址的首字节范围:0~127
  • B类地址的首字节范围:128-191
  • C类地址的首字节范围:192~223

还有如下这种表述方式:

  • A类地址的首位以0开始
  • B类地址的前2位以10开始
  • C类地址的前3位以110开始

正因如此,通过套接字收发数据时,数据传到网络后即可轻松找到正确的主机。

用于区分套接字的端口号

端口号是计算机为了区分程序中创建的不同套接字,而分配给套接字的序号,由16位组成,端口号唯一,可配分的范围在0~ 65535,其中0~10223是知名端口,一般分配给特定应用程序,所以应当分配范围之外的值。

端口号与套接字是一一对应关系,端口号与程序的不同通信功能是一一对应关系。

TCP套接字和UDP套接字不会共用端口号,所以允许重复。

数据传输过程示例

下面是基于IP地址的数据传输过程图:

在这里插入图片描述

主要步骤:

  1. 主机向203.211.217.202和203.211.172.103传输数据。
  2. 其中203.211.217和203.211.172是网络ID,通过网络ID可以把数据传输到指定的网络(路由器或交换机)。
  3. 202和103是主机ID,网络(路由器或交换机)通过主机ID将数据传输到指定的设备上。
  4. 操作系统收到数据后,根据数据包里的端口号,将数据传输到对应的程序上。

地址信息的表示

应用程序中使用的IP地址和端口号以结构体的形式给出了定义。

表示IPv4地址的结构体

此结构体将作为地址信息传递给bind函数。

struct sockaddr_in
{
    sa_family_t sin_family;  // 地址族
    uint16_t sin_port;       // 16位TCO/UDP端口号
    struct in_addr sin_addr; // 32位IP地址
    char sin_zero[8];        // 不使用
};

该结构体中提到的另一个结构体 in_addr 定义如下,它用来存放32位IP地址。

struct in_addr
{
    in_addr_t s_addr; // 32位IPv4地址
};

这些数据类型可以参考 POSIX,它是为 UNIX 系列操作系统设立的标准,它定义了一些其他数据类型,如下表所示:

数据类型名称数据类型说明声明的头文件
int8_tsigned 8-bit intsys/types.h
uint8_tunsigned 8-bit int (unsigned char)sys/types.h
int16_tsigned 16-bit intsys/types.h
uint16_tunsigned 16-bit int(unsigned short)sys/types.h
int32_tsigned 32-bit intsys/types.h
uint32_tunsigned 32-bit int(unsigned long)sys/types.h
sa_family_t地址族sys/socket.h
socklen_t长度sys/socket.h
in_addr_tIP地址,声明为uint32_tnetinet/in.h
in_port_t端口号,声明为uint16_tnetinet/in.h

看到这么长的类型表,有人不禁会问,为什么要搞出这么长的类型名呢?

其中一个很大的原因就是移植性的问题,如果适用于一个32位计算机的代码搬到64位的计算机上运行可定会出现由于位数不同导致的int被解释为不同的字节大小,这种问题是万万不可发生的。因此如果使用int32_t类型的数据,就能保证任何时候都占用4字节,即使转到不同字节的计算机上。

结构体sockaddr_in的成员分析

成员sin_family

每种协议族适用的地址族均不同。比如,IPv4使用4字节地址族,IPv6使用16字节地址族。

地址族(Address Family)含义
AF_INETIPv4网络协议中使用的地址族

AF_INET6 |IPv6网络协议中使用的地址族
AF_LOCAL| 本地通信中采用的UNIX协议的地址族

AF_LOCAL是为了说明具有多种地址族而添加的。

成员sin_port

该成员保存16位端口号,重点在于,它以网络字节序保存。

成员sin_addr

该成员保存32位地址信息,且也以网络字节序保存。为理解好该成员,应同时观察结构体in_addr。但结构体in_addr明为uint32_t,因此只需当作32位整数型即可。

成员sin_zero

无特殊含义。只是为使结构体sockaddr_in的大小和sockaddr结构体保持一致而插入的成员。必需填充为0,否则无法得到想要的结果。后面会另外讲解sockaddr。

从之前介绍的代码也可看出,sockaddr_in结构体变量地址值将以如下方式传递给bind函数。稍后将给出关于bind函数的详细说明,希望各位重点关注参数传递和类型转换部分的代码。

struct sockaddr_in serv_addr;

if(bind(serv_sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == -1)
	error_handling("bind() error");

此处重要的是第二个参数的传递。实际上,bind函数的第二个参数期望得到sockaddr结构体变量地址值包括地址族、端口号、IP地址等。

struct sockaddr
{
    sa_family_t sin_family; // 地址族
    char sa_data[14];       // 地址信息
};

这个结构体结构相对于sockaddr_in来说,它将后三个成员都放入sa_data之中。而这对于包含地址信息非常麻烦,继而有了新的结构体sockaddr_in。但是最后还是要转换为sockaddr型的结构体变量,再传递给bind函数即可。

网络字节序与地址变换

字节序与网络字节序

CPU内存保存数据有两种方式:

  • 大端序: 高位字节存放到低位地址
  • 小端序: 高位字节存放到高位地址

示例:

在这里插入图片描述

0x1234567中,0x12是最高位字节,0x67是最低位字节,大端序中先保存最高位。

在这里插入图片描述

0x1234567中,0x12是最高位字节,0x67是最低位字节,小端序中先保存最低位。

0x12和0x34构成的大端序系统值与0x34和0x12构成的小端序系统值相同。换言之,只有改变数据保存顺序才能被识别为同一值。

如果大端序系统传输数据0x1234时未考虑字节序问题,而直接以0x12、0x34的顺序发送。结果接收端以小端序方式保存数据,因此小端序接收的数据变成0x3412,而非0x1234,就会出现问题。

正因如此,在通过网络传输数据时约定统一方式,这种约定称为网络字统一节序(Network Byte Order),非常简单——统一为大端序。因此,所有计算机接受数据时应识别该数据时网络字节格式,小端序系统传输数据时应转换为大端序的排列方式。

字节序转换

为了统一标准,在网络传输前,得先把主机数据数组转化为大端序的网络字节序格式,下面是四种转换字节序的函数:

unsigned short htons(unsigned short);
unsigned short ntohs(unsigned short);
unsigned long htonl(unsigned long);
unsigned long ntohl(unsigned long);

s指short,l指long,h指主机(host)字节序,n指网络(network)字节序。

因此,htons指,把short类型数据从主机字节序转换为网络字节序;ntohl指,把long类型数据从网络字节序转换为主机字节序。

示例程序:

#include <stdio.h>
#include <arpa/inet.h>

int main(int argc, char *argv[])
{
    unsigned short host_port = 0x1234;
    unsigned short net_port;
    unsigned long host_addr = 0x12345678;
    unsigned long net_addr;

    net_port = htons(host_port);
    net_addr = htonl(host_addr);

    printf("Host ordered port: %#x \n", host_port);
    printf("Network ordered port: %#x \n", net_port);
    printf("Host ordered address: %#lx \n", host_addr);
    printf("Network ordered address: %#lx \n", net_addr);
    
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/907948.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Android Studio 中的Gemini 推出更多人工智能开发功能

谷歌公司&#xff08;Google LLC&#xff09;今天发布了由其人工智能模型 “双子座”&#xff08;Gemini&#xff09;驱动的Android Studio的更多功能。 Android Studio中的 "双子座 "作为Android Studio&#xff08;一种软件编辑器&#xff09;的人工智能升级版于今…

基于物联网的户外环境检测装置教学文章

引言 随着物联网&#xff08;IoT&#xff09;技术的发展&#xff0c;越来越多的应用被广泛研究和应用于我们的日常生活中。户外环境检测装置是一种利用传感器、网络连接和数据分析技术&#xff0c;监测和分析环境数据&#xff08;如温度、湿度、空气质量等&#xff09;的设备。…

Javaweb梳理3——SQL概述+DDL语句1

Javaweb梳理3——SQL概述DDL语句1 Javaweb梳理3——SQL概述DDL语句13.1 SQL简介3.2 通用语法3.3 SQL分类3.4 DDL:操作数据库3.4.1 查询数据库3.4.2 创建数据库3.4.3 删除数据库3.4.4 使用数据库 Javaweb梳理3——SQL概述DDL语句1 3.1 SQL简介 英文&#xff1a;Structured Que…

【MWorks】Ubuntu 系统搭建

升级 Ubuntu系统 sudo apt-get update sudo apt-get upgrade安装流程 sudo chmod x 路径/文件.run安装 sudo 路径/文件.run安装过程中两个选项都填 y 打开安装对应的文件夹 运行 syslab.sh 文件&#xff0c;运行结束后&#xff0c;就可以在左上角开始搜索到syslab了。

Linux Qt 6安装Oracle QOCI SQL Driver插件(适用WSL)

本文参考 QOCI for the Oracle Call Interface (OCI)。 除一般的 Linux 系统外&#xff0c;本文也适用于 WSL 2。 在开始之前&#xff0c;如果没有安装 QOCI 插件&#xff0c;则试图链接 Oracle 数据库时会报错&#xff1a; Failed to create wl_display (No such file or dire…

电磁兼容(EMC):整改案例(六)Y电容过大导致雷击浪涌炸机

目录 1. 异常现象 2. 原因分析 3. 整改方案 4. 总结 1. 异常现象 某金属外壳带接地线的产品按GB/T 17626.5进行雷击浪涌测试&#xff0c;在L&#xff0c;N线对PE进行4kV浪涌电压测试时&#xff0c;出现炸机现象&#xff0c;AC-DC电源芯片损坏。而在L&#xff0c;N线间进行2…

WPF怎么通过RestSharp向后端发请求

1.下载RestSharpNuGet包 2.请求类和响应类 public class ApiRequest {/// <summary>/// 请求地址/// </summary>public string Route { get; set; }/// <summary>/// 请求方式/// </summary>public Method Method { get; set; }/// <summary>//…

C语言 | Leetcode C语言题解之第520题检测大写字母

题目&#xff1a; 题解&#xff1a; bool detectCapitalUse(char * word){int len strlen(word);int res 0;int index -1;if(len 1)return true;else{for(int i 0; i < len; i){if(isupper(word[i])){res;index i;}}}return res len || res 0 || (res 1 &&…

VidPanos:从随手拍摄的平移视频生成全景视频

在当今数字化时代,视频拍摄已经成为人们记录生活和分享经历的重要方式。然而,普通手机拍摄的视频往往受到视角的限制,无法完整地展现一个广阔的场景。今天,我们要介绍的 VidPanos 技术,为解决这个问题提供了一种创新的方法。 VidPanos 是由来自华盛顿大学、谷歌 DeepMind…

使用 LlamaIndex 实现的检索增强生成(RAG)

Retrieval Augmented Generation (RAG) using LlamaIndex — ROCm Blogs (amd.com) 2024 年 4 月 4 日 作者&#xff1a;Clint Greene. 先决条件 要运行本博客&#xff0c;您需要具备以下条件&#xff1a; Linux: 参见受支持的 Linux 发行版 ROCm: 参见安装说明 AMD GPU: 参…

【计网】深入理解NAT机制,内网穿透与内网打洞,代理服务

我没胆量犯错 才把一切错过 --- 林夕 《我对不起我》--- 一文了解NAT机制&#xff0c;代理服务&#xff0c;内网穿透 1 再谈 NAT 机制2 内网穿透与内网打洞3 代理服务器 1 再谈 NAT 机制 NAT机制我们在解决IP地址不足的问题中提到过。为了解决IP地址不足的问题&#xff0c;采…

京东毫秒级热key探测框架JD-hotkey

前言 对任意突发性的&#xff0c;无法预先感知的热点数据&#xff0c;包括热点数据&#xff08;如突发大量请求同一个商品&#xff09;、热用户&#xff08;如恶意爬虫刷子&#xff09;、热接口&#xff08;突发海量请求同一个接口&#xff09;等&#xff0c;一瞬间打到我们的服…

2025生物发酵展(济南)为生物制造产业注入新活力共谱行业新篇章

2025第十四届国际生物发酵展将于3月3-5日济南盛大举办&#xff01;产业链逐步完整&#xff0c;展会面积再创历史新高&#xff0c;展览面积较上届增涨至60000平方米&#xff0c;专业观众40000&#xff0c;品牌展商800&#xff0c;同期活动会议增加至50场&#xff0c;展会同期将举…

设计模式08-行为型模式1(命令模式/迭代器模式/观察者模式/Java)

五、行为型模式 **行为模式的定义&#xff1a;**行为型模式是对不同的对象之间划分职责和算法的抽象化。行为型模式定义了系统中对象之间的交互与通信&#xff0c;研究系统在运行时对象之间的相互通信与协作&#xff0c;进一步明确对象的职责&#xff0c;包括对系统中较为复杂的…

边缘计算网关在机床数据采集中的应用-天拓四方

随着工业4.0和智能制造的快速发展&#xff0c;机床作为制造业的核心设备&#xff0c;其数据采集与分析对于提升生产效率、保证产品质量、优化加工过程具有重要意义。传统的数据采集方式存在数据传输速度慢、实时性差、数据处理能力有限等问题。为了解决这些问题&#xff0c;边缘…

Navicat 连接远程腾讯云服务器的MySQL数据库

首先需要开放开放腾讯云安全端口&#xff0c;可以参考这个链接腾讯云服务器入站规则端口开放使用指南(CentOS系统)。 但是注意需要开放的是IPv6&#xff0c;这个可以通过netstat命令查看确认。 然后查看当前用户信息 select user, host from mysql.user一般看到的都是 localh…

Navicat for MySQL 错误:1251

mySql&#xff1a;8.4 Navicat for MySQL&#xff1a;11.0.10 企业版 绿色版 官网中关于mysql_native_password插件的说法&#xff1a;链接 1. 问题 连接数据库报错&#xff1a;1251 要求升级Navicat for MySQL 2. 原因 mysql中的mysql_native_password插件默认是关闭的 …

mysql5安装

1.下载安装包 https://downloads.mysql.com/archives/community/ mysql-5.7.44-1.el7.x86_64.rpm-bundle.tar tar -xvf mysql-5.7.44-1.el7.x86_64.rpm-bundle.tar2.安装依赖 yum -y install perl yum -y install net-tools yum install numactl libaio libaio-devel -y也可…

【MyBatis】【基于轻量型架构的WEB开发】课程 课后习题 章节测试

mybatis关联查询、缓存、注解 一. 单选题 1. 下列关于 <collection> 元素的描述正确的是&#xff08;&#xff09;。 A. MyBatis 就是通过 <collection> 元素来处理一对多关联关系的 B. <collection> 元素的属性与 <association> 元素完全相同 C.…

C++ | Leetcode C++题解之第528题按权重随机选择

题目&#xff1a; 题解&#xff1a; class Solution { private:mt19937 gen;uniform_int_distribution<int> dis;vector<int> pre;public:Solution(vector<int>& w): gen(random_device{}()), dis(1, accumulate(w.begin(), w.end(), 0)) {partial_sum(…