第12章 网络 (1)

news2025/1/11 20:54:52

目录

12.1 互联的计算机

12.2 ISO/OSI 和TCP/IP 参考模型

12.3 通过套接字通信

12.3.1 创建套接字

12.3.2 使用套接字

12.3.3 UDP套接字

12.4 网络实现的分层模型


本专栏文章将有70篇左右,欢迎+关注,查看后续文章。

网络相关的头文件数目巨大,所以单独放在 include/net,而不是 include/linux。

12.1 互联的计算机

分层处理各种传输问题。

12.2 ISO/OSI 和TCP/IP 参考模型

ISO:国际标准化组织。

        该组织定义了7层模型,即 OSI 模型。

        OSI:开放系统互联。

实际使用上图左侧的4层模型。

物理层:

        网卡和线缆等物理设备。(PHY层)

数据链路层:

        网卡驱动程序中实现。(MAC层)

网络层和传输层:

        内核协议栈中实现。

12.3 通过套接字通信

网络不能通过 open("/dev/net")来通信。

创建socket,将生成一个文件描述符,存在有对应inode。

        然后像操作文件一样,进行read / write读写。

12.3.1 创建套接字

创建套接字时,须指定地址族(即Domain),通信类型(即Type)。

int   socket(int   domain,    int   type,    int   protocol);

        domain 值有:

                AF_UNIX、AF_LOCAL         本地通信使用。

                AF_INET、AF_INET6           IP协议。

                AF_NETLINK                        netlink 报文。

                AF_PACKET                         RAW 报文。

        type 值有:

                SOCK_STREAM                   数据流,如 TCP。

                SOCK_DGRAM                    数据报,如 UDP。

                SOCK_RAW                         当domain 为AF_PACKET时使用。

        protocol:

                若为0,则内核选择默认协议。

AF_PACKET:

        作用:

                1. 允许应用层直接操作数据链路层的报文。如以太网帧。

                2. 可绕过网络层和传输层,进行直接收发,避免被过滤掉。

        使用场景:

                1. 高性能的数据包处理。

                2. 网络监控,抓包( tcpdump )。

                3. 应用层自定义特殊网络协议。

socket 系统调用实现:

        sock_create:

                1. sock   =   sock_alloc( );

                        sock->type   =   type;

                2. struct net_proto_family   *pf    =    net_families [ family ];

                        pf->create(net,   sock,   protocol,   kern);

                        // 即调用 inet_create 或 inet6_create 或 netlink_create 等。

bind 用于将socke 与本地IP/端口绑定。

int   bind(int   sockfd,    struct   sockaddr   *addr,    socklen_t   addrlen);

struct   sockaddr {                 // 可容纳任意地址族的通用地址结构。

        sa_family_t         sa_family;

        char                    sa_data [14];

}

struct   sockaddr_in {         // IPv4专用的地址结构体,可用struct sockaddr强转得到。

        sa_family_t            sin_family;

        __be16                  sin_port;         // 大端。

        struct in_addr         sin_addr;

        unsigned char         __pad[  ];

};

        struct   in_addr  {

                in_addr_t    s_addr;         // 具体IPv4的地址值。

        };

网络字节序是大端。

长度为1个字节的数据不区分大小端。

如何判断CPU是大端?小端?

int   main( )

{

        unsigned int   i   =   0x12345678;

        if ( *(( unsigned char * ) &i )   ==   0x78)

                printf("Little Endian \n");

        else (* (( unsigned char * ) &i )   ==   0x12)

                printf("Big Endian \n");

}

小端:低位字节在低地址,高位字节在高地址。

大端:高位字节在低地址,低位字节在高地址。

12.3.2 使用套接字

如何将一个套接字关联到eth0等网络接口?

        int   bind(int   sockfd,    const   struct sockaddr   *addr,    socklen_t   addrlen);

                addr:即本地接口的IP。

组播可以跨网段通信。

广播分为:

        物理广播:

                局域网所有设备。目的MAC为:FF-FF-FF-FF-FF-FF。

        逻辑广播:

                特定子网的所有设备。如 192.168.1.255。

编程举例: 将本地接口加入 224.0.0.1多播组。

struct   ip_mreq   {

        struct   in_addr      imr_multiaddr;         // 请求加入或退出的组播IP(目)

        struct   in_addr      imr_interface;         // 发送接口的 IP 地址(源)

};

struct   ip_mreq    mreq;

mreq.imr_multiaddr.s_addr    =    inet_addr("224.0.0.1");

mreq.imr_interface.s_addr    =    htonl(INADDR_ANY);

setsockopt(sockfd,    IPPROTO_IP,    IP_ADD_MEMBERSHIP,    &mreq,    sizeof(mreq));

recvfrom(sockfd,    buffer,    sizeof(buffer),    0,    NULL,    NULL);

TCP客户端与服务器编程

1. TCP客户端

sockfd    =    socket(AF_INET,    SOCKET_STREAM,    0);

connect(sockfd,    (struct sockaddr *)server,    sizeof(*server));

        //server中填充了服务器IP/PORT

write(sockfd,  ,  );

read(sockfd,  , );

注意:

        客户端无需使用 bind 函数。即不将 socket和 IP/port 绑定。因为:

                通常客户端主动发送报文。

                发送时,内核根据目的IP,查找路由表可确定出接口的IP,作为报文源IP。

                        而源端口号由内核动态分配一个可用。

2. TCP服务器

sockfd    =    socket(AF_INET,    SOCKET_STREAM,    0);

bind(sockfd,    (struct sockaddr *)server,    sizeof(*server));

        //socket与服务器IP、port 绑定。

listen(sockfd,    SOMAXCONN);

        // SOMAXCONN,即为创建的等待队列长度。

clientfd    =    accept(sockfd,    (struct sockaddr *)client,    &client_size);

read(clientfd,    buf,    1000);

write(clientfd,    buf,    1000);

netstat:查看TCP/IP连接状态。

        netstat -atnp:tcp连接状态。

                -a         display all sockets

                -n         不解析域名。

                -p         display PID/Program name for sockets

                -t         TCP

                -u         UDP

netstat     -antp         查看tcp连接状态。

netstat     -anup         查看udp连接状态。

12.3.3 UDP套接字

12.4 网络实现的分层模型

建议阅读 fs_initcall(inet_init);

1. 网络层:

struct   packet_type    ip_packet_type;

struct   packet_type    ipv6_packet_type;

struct   packet_type     ip_packet_type    =    {

        .type     =    cpu_to_be16(ETH_P_IP), // IP协议

        .func     =    ip_rcv,

};

2. 传输层

struct   proto    tcp_prot;

struct   proto    udp_prot;

struct   inet_protosw    inetsw_array[  ]     =

{

        {

                .type           =      SOCK_STREAM,

                .protocol     =      IPPROTO_TCP,

                .prot            =      &tcp_prot,                       //函参为:struct   sock    *sk;

                .ops             =      &inet_stream_ops,         //函参为:struct   socket    *sock;

        },

        {

                .type            =     SOCK_DGRAM,

                .protocol      =     IPPROTO_UDP,

                .prot             =     &udp_prot,

                .ops              =     &inet_dgram_ops,

        },

        ...

}

const struct   proto_ops    inet_dgram_ops    =    {

        .family            =    PF_INET,

        .bind               =    inet_bind,

        .connect         =    inet_dgram_connect,

        .accept           =    sock_no_accept,

        .listen             =    sock_no_listen,

        .setsockopt     =    sock_common_setsockopt,

        .getsockopt     =    sock_common_getsockopt,

        .sendmsg        =     inet_sendmsg,

        .recvmsg         =     inet_recvmsg,

};

struct  proto    udp_prot    =    {

        .name             =    "UDP",

        .connect         =     ip4_datagram_connect,

        .destroy          =     udp_destroy_sock,

        .setsockopt     =     udp_setsockopt,

        .getsockopt     =    udp_getsockopt,

        .sendmsg        =     udp_sendmsg,

        .recvmsg         =     udp_recvmsg,

};

struct   proto_ops    inet_dgram_ops 中的

        .connect    =    inet_dgram_connect,

int   inet_dgram_connect(struct socket   *sock,     struct sockaddr   *uaddr,

  int   addr_len,     int   flags)

{

        struct   sock    *sk     =     sock->sk;

        return     sk->sk_prot->connect(sk,     uaddr,     addr_len);

                //即struct proto    udp_prot中的 ip4_datagram_connect。

}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

两台电脑之间记事本内容如何转移?

记事本是我们日常生活中不可或缺的工具,它轻便、简单,方便我们随时记录生活中的点滴、工作中的灵感或重要的事务。比如,在会议中快速记下关键点,或者在阅读时捕捉一闪而过的想法。然而,随着数字化生活的推进&#xff0…

重塑“我店”平台:绿色积分引领的数字消费新纪元

在数字化转型的洪流中,“我店”平台凭借其创新的绿色积分体系异军突起,成为市场中的璀璨新星。本文将深度剖析“我店”的运营模式、市场效应及其如何通过绿色积分机制开创消费新潮流。 一、崛起之路与市场震撼力 自2021年盛夏在上海启航以来&#xff0c…

研讨会邀请函-Parasoft TÜV Rheinland|SOA架构下符合功能安全要求的软件自动化测试解决方案

尊敬的技术先锋, 在汽车行业的数字化转型浪潮中,软件安全已成为我们共同关注的焦点。Parasoft 联合 TV Rheinland,荣幸地邀请您参与我们即将举办的专业研讨会,与行业领袖一同探索SOA架构下的功能安全软件开发测试方案。 会议议程…

支付宝小程序websocket长连接(心跳版本)

注意点: 关闭连接一定要把那些开下来的监听全部关闭掉 1.开启连接 /*长连接*/ connectWebSocket() {let that this;my.connectSocket({url: ws://192.xx.8.xx:7780/charger-service-netty/websocket/${uni.getStorageSync(chargePointId)},header: {AccessType: a…

三种相机模型总结(针孔、鱼眼、全景)

相机标定 文章目录 相机标定前言 前言 我们最常见的投影模型Perspective Projection Model描述的就是针孔相机的成像原理。从上面的图根据相似三角形可以得出 参考链接 https://zhuanlan.zhihu.com/p/540969207 相机标定之张正友标定法数学原理详解(含python源码&a…

楼宇智慧公厕系统实时卫生状况一目了然

在科技飞速发展的今日,楼宇智慧公厕系统如一颗璀璨的新星,悄然改变着我们的生活。它以先进的技术手段,让公厕的实时卫生状况一目了然,为人们带来了全新的如厕体验。 当我们步入一栋现代化的楼宇,对公厕的期待不再仅仅是…

JVM 内存结构了解吗,每个区域都存放什么数据?

Java 程序是运行在 JVM 之中的,所有对象的创建和分配都在 JVM 中。 内存结构: 方法区:各线程共享,主要存放类信息、常量、静态变量 虚拟机栈:线程私有,主要存放基本数据类型(int、char、float……

Blazor开发框架Known-V2.0.9

V2.0.9 Known是基于Blazor的企业级快速开发框架,低代码,跨平台,开箱即用,一处代码,多处运行。本次版本主要是修复一些BUG和表格页面功能增强。 官网:http://known.pumantech.comGitee: https:…

什么是蒙太奇谎言

蒙太奇谎言,可以理解为不表述全部事实,而是进表达部分事实,让听众形成错误的观点。 比如,某X国家队水平很差,从来没进入过世界杯。 可以这样说:世界足球强国巴西,从来没在世界大赛上赢过X国家队…

C++构造数据类型|枚举类型

C构造数据类型|枚举类型 1. 枚举类型1.1 函数重载的定义1.2 枚举类型的声明1.3 例1:1.4 例2: 2. 枚举类型的定义说明3. 枚举类型的使用3.1 枚举变量的赋值3.2 枚举变量的运算3.3 枚举变量的输入3.4 注意事项 4 示例代码 1. 枚举类型 1.1 函数重载的定义…

cdr工具介绍之刻刀工具

在日常的生活当中,在很多时候我们会遇到各种各样的难题,但软件cdr他就是一个神奇的存在,因为他能帮助我们解决很多专业方面的的知识。尽管他的内容相比较其他的一些设计软件而言相对于较为少,但是他确实一个非常适合于平常的工作学…

arthas源码刨析:arthas-core (2)

文章目录 attach JVMagent**ArthasBootstrap** arthas-core的启动可以从上一篇做参考 参考 pom,即启动是调用的 Arthas 的 main 方法 attach JVM JVM提供了 Java Attach 功能,能够让客户端与目标JVM进行通讯从而获取JVM运行时的数据,甚至可以…

算法-矩阵置零(73)

leetcode题目链接 这道题因为要求在O(1)的空间复杂度下面完成,所以最好的情况就是利用矩阵本身有的元素进行代码编写,而不另外开辟空间。 所以思路如下: 1.遍历第一行第一列,观察是否需要置0&#xff0c…

【面试实战】2024-08-22-面试总结

文章目录 1. 讲讲内存管理2. 什么是智能指针?有哪些种类?分别应用于哪些场景? 1. 讲讲内存管理 栈和堆的区别: ①栈和堆都是用来存储程序数据的内存区域。栈上的内存区域是有限的,栈用来存储局部变量和函数的调用信息。…

史上最强座舱AI芯登场,座舱「百模大战」爆发前夜

作者 |张马也 编辑 |德新 一场座舱大模型的竞赛,正在拉开序幕。 8月,英特尔在深圳举办AI座舱产品暨车载独立显卡发布会上。 会上,其发布了首款锐炫车载独立显卡ARC A760-A,这在已经高度内卷的座舱市场,又投下一颗重…

微软发布 Phi-3.5 系列模型,涵盖端侧、多模态、MOE;字节 Seed-ASR:自动识别多语言丨 RTE 开发者日报

开发者朋友们大家好: 这里是 「RTE 开发者日报」 ,每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE(Real-Time Engagement) 领域内「有话题的 新闻 」、「有态度的 观点 」、「有意思的 数据 」、「有思考的 文…

DatePicker 两个日期选择框的时间范围设置不可选日期

思路 截至时间的不可选择日期,通过监听开始时间,生成

tp5php7.4配置sqlserver问题汇总

先修改database.php文件 查看php版本选择sqlserver扩展 通过百度网盘分享的文件:sqlserver 链接:https://pan.baidu.com/s/1zrIV8VWQZM9miLpyH01Aww?pwdxdgx 提取码:xdgx 通过我的分享链接复制自己需要的dll到php的ext下 在php.ini里添加扩…

电子看板助力线缆工厂生产数字化改善

在当今数字化时代,线缆工厂面临着日益激烈的市场竞争和不断提高的客户需求。为了提高生产效率、降低成本、提升产品质量,越来越多的线缆工厂开始引入电子看板系统,实现生产数字化改善。 一、线缆工厂生产面临的挑战 1、生产过程复杂 线缆生产…

【与C++的邂逅】--- 类和对象(中)

Welcome to 9ilks Code World (๑•́ ₃ •̀๑) 个人主页: 9ilk (๑•́ ₃ •̀๑) 文章专栏: 与C的邂逅 本篇博客我们将学习类和对象中,认识类的六个默认成员函数以及实现日期类。下图为本节思维导图。 🏠 类的6个默认成员函…