• UNIX 网络编程笔记-CH3:套接字编程简介


    IPv4套接字地址结构

    struct in_addr {
        in_addr_t s_addr;  
    };
    
    struct sockaddr_in {
        uint8_t             sin_len;        /* length of structure (16) bytes */
        sa_family_t         sin_family;     /* AF_INET */
        in_port_t           sin_port;       /* 16-bit TCP/UDP port, network byte order(big-endian) */
        struct in_addr      sin_addr;       /* 4-byte IPv4 address, network byte */
    
        char                   sin_zero[8]; /* unused */   
    }

    共16字节,编程时需要设置的一般就是sin_family, sin_port, sin_addr这三个字段。因为这是IPv4对应的套接字地址结构体所以有sin_family=AF_INET,后两个字段需要通过换转函数把本机字节序的值变为网络字节序(大端)。

    通用套接字地址结构

    套接字接口除了处理IPv4对应的套接字地址结构外,还需要支持其他各种套接字地址结构,如IPv4,Unix套接字等。所以在void*指针类型尚未出现前,定义了一个通用套接字结构体:

    struct sockaddr {
        uint8_t           sa_len;
        sa_family_t       sa_family;
        char              sa_data[14];
    };

    相应的各套接字函数的地址参数都使用了struct sockaddr*类型的参数,使用时把各个类型的套接字地址结构体指针都强制转换为struct sockaddr*,这样单个套接字函数可以根据sa_family和长度复制数据并对不同类型的套接字分别处理了。如bind函数:

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

     套接字地址参数值传递

    从进程向内核传递套接字地址的函数有:

    1. bind(int fd, struct sockaddr* addr, int addrlen)

    2. connect(int fd, struct sockaddr* addr, int addrlen)

    3. sendto

    从内核到进程传递套接字地址的函数有:

    1. accept(int fd, struct sockaddr* addr, int* len),len在调用时向内核指明地址结构大小,在返回时指明实际存储的数据大小

    2. recvfrom

    3. getsockname

    4. getpeername

    字节序转换函数

    uint16_t htons(uint16_t host16bitvalue);
    uint32_t htonl(uint32_t host32bitvalue);
    uint16_t ntohs(uint16_t net16bitvalue);
    uint32_t ntohl(uint32_t net32bitvalue);

    h-host, n-network, s-short, l-long int==>int

    地址字符与数值转换

    IPv4地址可以使用点分十进制也可以使用直接的数值(网络序),书中推荐使用下面两个函数进行转化

    #include <arpa/inet.h>
    
    int inet_pton(int family, const char* str, void* addrptr);
    
    const char* inet_ntop(int family, const void* addptr, char* strbuf, size_t len);

    对于IPv4来说addrptr应该取sockaddr_in.sin_addr的地址,常用的类似功能的函数有

    #include <arpa/inet.h>
    
    int inet_aton(const char*strptr, struct in_addr *addrptr);
    
    in_addr_t inet_addr(const char* strptr);
    
    char* inet_ntoa(struct in_addr inaddr);
  • 相关阅读:
    配置cinder使用NFS后端
    配置glance使用NFS后端
    制作windows镜像
    fuel健康检查Heat失败的原因
    重启OpenStack服务步骤
    改变nova-compute默认位置的方法
    改变cinder默认vg的方法
    centos lvm常用命令
    【一天一个canvas】图像处理教程(十二)
    【一天一个canvas】阴影效果呈现方法(十一)
  • 原文地址:https://www.cnblogs.com/lailailai/p/4338529.html
Copyright © 2020-2023  润新知