• Socket编程


    API编程部分:http://www.cnblogs.com/Jimmy1988/p/7895213.html

    1. 协议简介

    此处,我们主要介绍Linux编程常用的三种协议(TCP/UDP/IP), 关于三种协议的定义,可参见各自的头文件:

    • /usr/include/linux/tcp.h
    • /usr/include/linux/udp.h
    • /usr/include/linux/ip.h

    ①. TCP

    mark

    /*
     * Come from /usr/include/linux/tcp
     */
    struct tcphdr {
        __be16  source;
        __be16  dest;
        __be32  seq;
        __be32  ack_seq;
    #if defined(__LITTLE_ENDIAN_BITFIELD)
        __u16   res1:4,
            doff:4,
            fin:1,
            syn:1,
            rst:1,
            psh:1,
            ack:1,
            urg:1,
            ece:1,
            cwr:1;
    #elif defined(__BIG_ENDIAN_BITFIELD)
        __u16   doff:4,
            res1:4,
            cwr:1,
            ece:1,
            urg:1,
            ack:1,
            psh:1,
            rst:1,
            syn:1,
            fin:1;
    #else
    #error  "Adjust your <asm/byteorder.h> defines"
    #endif
        __be16  window;
        __sum16 check;
        __be16  urg_ptr;
    };
    
    
    Unit bits Function
    源端口 16 源端口和IP地址的作用是标识报文的返回地址
    目的端口 16 端口指明接收方计算机上的应用程序接口
    常用端口:
     - ftp/tftp:  20、21/69
     - SSH:  22
     - telent: 23
     - smtp:  25
     - http/https:  80/443
     - pop3/snmp:  110/163
    (详细信息参见:http://cert.sjtu.edu.cn/doc/linux/ch-ports.html)
    或者参见Linux的文件 /usr/services
    序号 32 本报文段发送的数据组的第一个字节的序号
    确认序号 32 下一个期待收到的字节序号
    数据偏移/首部长度 4 TCP报头的长度
    报头长度=首部长度*32bit
    保留 4 为将来定义新的用途保留,现在一般置0
    URG 1 紧急指针标志
    - 为1时表示紧急指针有效
    - 为0则忽略紧急指针
    ACK 1 确认序号标志
    - 为1时表示确认号有效
    - 为0表示忽略确认号字段
    PSH 1 push标志
    - 1:指示接收方在接收到该报文段以后,
      应尽快将这个报文段交给应用程序,而不是在缓冲区排队
    RST 1 重置连接标志
    用于重置由于主机崩溃或其他原因而出现错误的连接。
    或者用于拒绝非法的报文段和拒绝连接请求
    SYN 1 同步序号
    用于建立连接过程,在连接请求中,
    - SYN=1和ACK=0表示该数据段没有使用捎带的确认域;
    - SYN=1和ACK=1,而连接应答捎带一个确认
    FIN 1 finish标志,用于释放连接
    - 1: 表示发送方已经没有数据发送了,即关闭本方数据流
    窗口 16 滑动窗口大小
    用来告知发送端接受端的缓存大小,
    以此控制发送端发送数据的速率,
    从而达到流量控制
    校验和 16 奇偶校验
    此校验和是对整个的 TCP 报文段,包括 TCP 头部和 TCP 数据,以 16 位字进行计算所得;
    由发送端计算和存储,并由接收端进行验证。
    紧急指针 16 只有当 URG 标志置 1 时紧急指针才有效
    紧急指针是一个正的偏移量,和顺序号字段中的值相加
    表示紧急数据最后一个字节的序号。
    选项和填充 32 表示本端所能接受的最大报文段的长度

    ②. UDP

    mark

    /*
     * Come from /usr/include/linux/udp.h
     */
    struct udphdr {
        __be16  source;
        __be16  dest;
        __be16  len;
        __sum16 check;
    };
    
    
    Unit bits Function
    源端口 16 源端口号。在需要对方回信时选用。不需要时可用全0
    目的端口 16 目的端口号。这在终点交付报文时必须要使用到
    长度 16 UDP用户数据报的长度,其最小值是8(仅有首部)
    校验和 16 检测UDP用户数据报在传输中是否有错。有错就丢弃

    ③. IP

    mark

    /* 
     * Comes from /usr/include/linux/ip.h
     */
     
    struct iphdr {
    #if defined(__LITTLE_ENDIAN_BITFIELD)
        __u8    ihl:4,
            version:4;
    #elif defined (__BIG_ENDIAN_BITFIELD)
        __u8    version:4,
            ihl:4;
    #else
    #error  "Please fix <asm/byteorder.h>"
    #endif
        __u8    tos;
        __be16  tot_len;
        __be16  id;
        __be16  frag_off;
        __u8    ttl;
        __u8    protocol;
        __sum16 check;
        __be32  saddr;
        __be32  daddr;
        /*The options start here. */
    };
    
    
    Unit bits Function
    version 4 IP协议的版本
    IHL
    (Internet Header Length)
    4 IP报头的长度
    固定部分的长度(20字节)和可变部分的长度之和
    Length=IHL*32bit
    TOS
    (Type Of Service)
    8 IP数据包的服务类型
    总长度 16 IP报文的总长度
    报头的长度和数据部分的长度之和
    标识 16 唯一的标识主机发送的每一分数据报
    通常每发送一个报文,它的值加一。
    当IP报文长度超过传输网络的MTU(最大传输单元)时必须分片,
    这个标识字段的值被复制到所有数据分片的标识字段中,
    使得这些分片在达到最终目的地时
    可以依照标识字段的内容重新组成原先的数据。
    标志 3 R、DF、MF三位
    目前只有后两位有效
    - DF位:为1表示不分片,为0表示分片;
    - MF:为1表示“更多的片”,为0表示这是最后一片
    片位移 13 本分片在原先数据报文中相对首位的偏移位
    (需要再乘以8)
    TTL
    (Time To Live)
    8 IP报文所允许通过的路由器的最大数量
    每经过一个路由器,TTL减1;
    当为0时,路由器将该数据报丢弃
    协议 8 指出IP报文携带的数据使用的是那种协议,
    以便目的主机的IP层能知道要将数据报上交到哪个进程。
    - TCP: 6
    - UDP: 17
    - ICMP: 1
    - IGMP: 2
    首部校验和 16 计算IP头部的校验和,
    检查IP报头的完整性
    源IP地址 32 标识IP数据报的源端设备
    目的IP地址 32 标识IP数据报的目的地址。

    2. IPv4相关操作

    /* Internet address.  */
    typedef uint32_t in_addr_t;
    struct in_addr
    {
        in_addr_t s_addr;
    };
    

    ①. IPv4地址转换

    函数 参数 返回值 描述
    in_addr_t inet_addr(
    const char *cp)
    cp:十进制字符串 成功:0
    失败:非0
    将点分十进制字符串
    转换为32位网络字节(大端)
    in_addr_t inet_network(
    const char *cp)
    cp:十进制字符串 成功:32bit 地址
    失败:非0
    将点分十进制字符串
    转换为32位主机字节顺序的IP地址
    char *inet_ntoa(
    struct in_addr in)
    in:32bit网络IP 点分十进制字符串 将32bit的网络顺序字节
    转化为点分十进制字符串方式
    int inet_aton(
    const char *cp,
    struct in_addr *inp
    1.cp: 欲转化的点分十进制IP的首地址
    2.inp:转化结果的地址空间首地址
    成功:0
    失败:非0
    点分十进制字符串
    转化为32bit的网络顺序字节顺序

    ②. 获取ID

    函数 参数 返回值 描述
    in_addr_t inet_lnaof(
    struct in_addr in)
    in:ip地址 返回标准主机ID 获取标准主机ID
    in_addr_t inet_netof(
    struct in_addr in)
    in:ip地址 返回标准主机ID 获取标准网络ID
    struct in_addr inet_makeaddr(
    int net, int host)
    1.net:网络ID
    2.host:主机ID
    返回IP 将主机ID和网络ID合成标准IP

    3. 大端小端

    • 大端:Big-Endian
      即内存高地址存放数据的低字节:如0x1234,存放在0x4000~0x4001,则0x4000存0x12,0x4001存0x34
      网络字节顺序统一采用大端
    • 小端:Little-Endian
      与大端相反,即高地址存放高字节
      x86系列处理器为小端模式

    ①.程序判断大小端

    #include <stdio.h>
    
    int main()
    {
        union end_un
        {
            unsigned short int word;
            char ch;
        }endian;
    
        endian.word = 0x1234;
        if(endian.ch == 0x12)
        {
            printf("This is Big-Endian!
    ");
        }
    
        else if(endian.ch == 0x34)
        {
            printf("This is Little-Endian!
    ");
        }
    
        return 0;
    }
    

    ②. 字节顺序转化函数

    头文件:#include <arpa/inet.h>

    函数数 功能
    uint32_t htonl(uint32_t hostlong) long host to net
    uint16_t htons(uint16_t hostshort) short host to net
    uint32_t ntohl(uint32_t netlong ) long net to host
    uint16_t ntohs(uint16_t netshort ) short net to host
  • 相关阅读:
    python包管理工具pip使用手册
    Java 校验是否为连续的区间
    AngularJS的uigrid的列表数据实现换行
    家族信托二十大功能全解读
    AngularJS前端,directive的template的点击事件 绑定
    递归和循环的区别
    Oracle数据库锁表排查
    JavaScript判断对象是否是NULL(转)
    西安出差已经一年多了
    发现个了不得的项目
  • 原文地址:https://www.cnblogs.com/Jimmy1988/p/7839940.html
Copyright © 2020-2023  润新知