sockaddr和sockaddr_in的异同

sockaddr结构体

struct sockaddr { 
	unsigned short sa_family; // 地址族, AF_xxx 
	char sa_data[14]; //14字节的协议地址
}; 

上面是通用的socket地址

sockaddr_in的结构体

struct sockaddr_in { 
short int sin_family; //地址族,AF_xxx 在socket编程中只能是AF_INET 
unsigned short int sin_port; // 端口号 (使用网络字节顺序) 
struct in_addr sin_addr; //存储IP地址 4字节
unsigned char sin_zero[8]; // 总共8个字节,实际上没有什么用,只是为了和struct sockaddr保持一样的长度 
}; 


两者可以进行相互转换。


struct in_addr就是32位IP地址。 

struct in_addr { 
  union {
    struct {
      u_char s_b1,s_b2,s_b3,s_b4; 
    } S_un_b;
    struct { 
      u_short s_w1,s_w2; 
    } S_un_w;
    u_long S_addr; //按照网络字节顺序存储IP地址 
  } S_un;
  #define s_addr S_un.S_addr
}; 

我们在为bind()函数准备ip、port值时,可以直接将值赋给结构体:sockaddr_in,请看下面的例子:

int serverfd = -1;

//本地地址、端口赋值
struct sockaddr_in sin;
//PROTOCL FAMILY 协议族,使用AF_INET、PF_INET都可以
sin.sin_family = PF_INET;

//htons()函数将一个16位的无符号短整型数据由主机分列体式格式转换成收集分列体式格式
sin.sin_port = htons(atoi("8183"));

//inet_addr()函数将网络地址转化为二进制数字
sin.sin_addr.s_addr = inet_addr("192.168.0.1");
serverfd = socket(sin.sin_family,SOCK_STREAM,IPPROTO_TCP);
if(serverfd < 0){
  printf("创建server的socket套接字失败");
  return -1;
}

bzero(&(sin.sin_zero), 8); // zero the rest of the struct 
ret = bind(serverfd,(const struct sockaddr*)&sin,sizeof(sin));
if(ret){
  printf("绑定本地地址、端口失败");
  return -1;
}

inet_addr()是将一个点分制的IP地址(如192.168.0.1)转换为上述结构中需要的32位IP地址(0xC0A80001)。
填值的时候使用sockaddr_in结构,而作为函数(如socket, listen, bind等)的参数传入的时候转换成sockaddr结构就行了,因为两个结构体都是16个字符长,可以相互转换。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值