sockaddr_in / sockaddr 的理解 和 使用到的一些网络函数(sock inet_*)

1,struct sockaddr 、struct sockaddr_in 和 struct in_addr 

通用地址结构体(16字节)
struct sockaddr{
    unsigned short sa_family;
    char sa_date[14];
};

IPv4结构体(16字节)
struct sockaddr_in{
    unsigned short sin_family;
    unsigned short sin_port;
    struct in_addr sin_addr;
    char sin_zero[8];   //占位,与通用结构体大小保持一致
};

struct in_addr{
    unsigned int s_addr;  //无符号32位网络地址
};

以前总是混淆这几个结构体在网络编程中的使用,就目前的理解来看:

  •    sockaddr_in用于编写sock代码时,方便我们对地址结构的赋值,所以在编写应用层代码时候,地址结构的初始化使用该结构体。
  •    sockaddr -->通用的地址结构,目前主要使用得到的地方在accept、connect函数中,这几个API使用的我们 初始化的地址结构时,需要强制转换为struct sockaddr *,为了方便理解,相当于sockaddr用于内核识别地址结构,sockaddr_in用于我们在应用层的代码编程。
  • in_addr : 其结构体中只有一个变量,用于存储数值类型的ip地址,一般会在地址转换函数中使用到。
  sin_port和sin_addr都必须是网络字节序(NBO)
  
  程序员不应操作sockaddr,sockaddr是给操作系统用的
  
  程序员应使用sockaddr_in来表示地址,sockaddr_in区分了地址和端口,使用更方便。
  
  in_addr 在地址函数转换调用时使用
  

2、网络编程中频繁使用的函数简单总结

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

domain:域,
    可以理解为是网络中的(AF_INIT | PF_INIT),
    还是操作系统中的 (AF_UNIX |PF_UNIX == AF_LOCAL/PF_LOCAL)
type:
    SOCK_STREAM | SOCK_DGRAM

return :
    -1 ERROR
//绑定套接字与网络地址
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)

参数:
    sockfd:待连接套接字
    addr:包含本地地址(IP+PORT)的通用地址结构体的指针
    addrlen:地址结构体大小

return : -1 ERROR  0 SUCCESS
/*
    刚刚讲的sockaddr 结构是这个函数的参数,所以当我们使用sockaddr_in时,调用bind函数就需要进行地    
   址转换
*/

//监听套接字
    listen(int sockfd , int backlog)  
    backlog:最大同时接收连接请求个数

return :
    成功:0,并将 sockfd 设置为监听套接字
    失败:-1


//等待对端连接请求
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
参数:
    sockfd:监听套接字
    addr:通用地址结构体,用以存储对端地址(IP+PORT)
    addrlen:参数 addr 的存储区域大小

return:
    成功:已连接套接字(非负整数)
    失败:-1

/*
    该等待地址链接函数:也使用的通用地址结构
    */

地址转换函数的使用:

inet_aton( ) 
    #include <arpa/inet.h>
    将strptr所指的字符串转换成32位的网络字节序二进制值
    int inet_aton(const char *strptr, struct in_addr *addrptr);

inet_ntoa( )
    将32位网络字节序二进制地址转换成点分十进制的字符串。
    char *inet_ntoa(stuct in_addr inaddr);

inet_pton()
    将IPV4/IPV6的地址转换成binary格式
	int inet_pton(int af, const char *src, void *dst);

inet_ntop()
    将二进制地址转化为文本地址
    const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
 
//在编程时需要地址转来转去,一般使用下面的函数
inet_addr( )
    功能同上,返回转换后的地址。
    int_addr_t inet_addr(const char *strptr);

代码测试:

#include <stdio.h>
#include <stdlib.h>

//函数引用头文件  
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main()
{

    char mySip[16]="192.168.100.36";
    unsigned int myNip=0xC0A86424;

    //inet_addr
    unsigned int swapIP = {0};
    swapIP = inet_addr(mySip);
    printf("inet_addr  ip: %x\n", swapIP);

    //inet_aton()
    struct in_addr serIP = {0};
    inet_aton( mySip, (struct in_addr *)&serIP);
    printf("inet_aton ip: %x\n", serIP.s_addr);

    //inet_ntoa()
    char *pIp =NULL;
    pIp = inet_ntoa( serIP );
    printf("inet_ntoa ip: %s\n", pIp);

    //inet_pton()
    unsigned int pnIP = 0;
    if(0 == inet_pton( AF_INET, "192.168.100.36", (void *)&pnIP))
    {
        printf("inet_pton Some Error\n");
    }else
        printf("inet_pton ip: %x\n" , pnIP);

    //inet_ntop()
    char buf[20]={0};
    if(NULL == inet_ntop( AF_INET, (void *)&pnIP, buf, 20))
    {
        printf("inet_ntop Some Error\n");

    }else
        printf("inet_ntop ip: %s\n" , buf);

    return 0;
}

结果:

[root@hero work]# ./a.out 
inet_addr  ip: 2464a8c0
inet_aton ip: 2464a8c0
inet_ntoa ip: 192.168.100.36
inet_pton ip: 2464a8c0
inet_ntop ip: 192.168.100.36

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值