zoukankan      html  css  js  c++  java
  • C语言实现ping命令(一)

    ping命令使用到了网络中的ICMP协议:

    关于ICMP介绍看这里:https://www.cnblogs.com/wanghao-boke/p/11670473.html

    网络地址信息

    地址信息表示:

    网络传输时地址信息包括:

    • 地址族(基于IPV4还是IPv6的地址族)
    • IP地址
    • 端口号

    使用相关结构体来纪录地址信息:

    struct sockaddr_in{
        sa_family_t        sin_family;     // 地址族
        uint16_t        sin_port;        // 端口号
        struct in_addr  sin_addr;          // 32位IP地址
        char             sin_zero[8];    // 不使用
    };
    
    struct in_addr{
        in_addr_t     s_addr;        // 32位IP地址
    };
    
    struct in_addr{
        in_addr_t     s_addr;        // 32位IP地址
    };
    
    #define in_addr_t uint32_t    //无符号整型32位

    还可以使用以下结构体:

    struct sockaddr{
        sa_family_t    sin_family;     // 地址族
        char         sa_data[14]; // IP地址和端口
    };

    成员sa_data保存的信息包含IP地址和端口号,剩余部分填充0。

    在使用时定义信息地址时使用struct sockaddr_in结构体,然后将该结构体类型转成struct sockaddr结构体传递给网络编程。

    主机字节序与网络字节序

    在CPU中,4字节整型数值1在内存空间保存方式是不同的。

    4字节整型数值1可用二进制表示如下:
    00000000 00000000 00000000 00000001

    而在有些CPU则以倒序保存

    00000001 00000000 00000000 00000000

    这两种CPU解析数据的方式分别被称为

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

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

    为了使发送和接受双方主机的CPU在解析数据方式上保持一致,在网络传输数据时约定统一为大端序,这种约定被称之为网络字节序。

    所以在网路传输数据前,需要把数据数组转换成大端序格式再进行网络传输,接收到网络数据后,需要转换本机字节格式然后进行后续处理。该步骤都会有关函数来处理。

    我们需要做的就是向struct sockaddr_in结构体变量种填充IP地址和端口数据的时候转换该格。

    具体转换字节序的函数有以下几种方式:

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

    htonl/htons中h表示(host)主机字节序,n表示(network)网络字节序,s表示short,l指的是long(linux中long类型和int一样只占4字节)。

    实例:

    /*test.c*/
    #include<stdio.h>
    #include<arpa/inet.h>
    
    int main()
    {
        unsigned short hosts = 0x1234;
        unsigned short nets;
        unsigned hostl = 0x12345678;
        unsigned netl;
    
        nets = htons(hosts);
        netl = htonl(hostl);
    
        printf("Host order short: %#x 
    ", hosts);
        printf("NetWork order short: %#x 
    ", nets);
    
        printf("Host order long: %#x 
    ", hostl);
        printf("NetWork order long: %#x 
    ", netl); 
    
        return 0;   
    }

    运行结果:

    Host order short: 0x1234

    NetWork order short: 0x3412

    Host order long: 0x12345678

    NetWork order long: 0x78563412

    扩展:

    Intel系统的CPU采用的都是小端序标准。

  • 相关阅读:
    Windows向虚拟机Linux传输文件方法
    Postgresql ERROR: permission denied for relation app_info
    Spring Boot: Cannot determine embedded database driver class for database type NONE
    零宽度正预测先行断言是什么呢,看msdn上的官方解释定义
    php 的curl 模拟登陆
    使用ProxychainsMac下安装及配置
    利用onekeyup即可实现验证码的点击刷新功能
    程序中使用gc_enable() 和 gc_disable()开启和关闭
    通过ReflectionMethod,我们可以得到Person类的某个方法的信息
    order by id asc得出的排序是什么原理
  • 原文地址:https://www.cnblogs.com/wanghao-boke/p/12180697.html
Copyright © 2011-2022 走看看