Linux socket 结构体关系 及 获得本地IP和广播地址

/*=============================================================
注意:结构体之间不能直接进行强制转换, 必须先转换成指针类型才可以进行结构体间的类型转换, 这里需要明确的定义就是什么才叫强制转换.
强制转换是将内存中一段代码以另一种不同类型的方式进行解读, 因此转换的空间必须与源空间一一对应.
而结构体则是由不固定的多种类型变量组合而成, 因此强制转换时并不确定原格式与目标格式确定的对应关系, 例如一个结构体为3个变量, 而另一个则为2个, 那么就无法确定如何分配.
因此最简单的让计算机可以理解的方式就是先将结构体转换成指针, 然后将指针转换成目标格式, 再读取转换后的指针, 这样计算机就会按照指针的格式读取特定目标代码段了.

//接口配置结构体
#include<net/if.h>
struct ifconf {
    int ifc_len;// 缓冲区的大小
    union {
  caddr_t ifcu_buf;  // input from user->kernel
        struct ifreq *ifcu_req; // return of structures returned 注意:是指针类型, 要指向目标数据
    }ifc_ifcu;
};
#define  ifc_buf ifc_ifcu.ifcu_buf //buffer address
#define  ifc_req ifc_ifcu.ifcu_req //array of structures returned

//接口地址结构体
#include<net/if.h>
struct ifreq{
    char ifr_name[IFNAMSIZ];// interface name, e.g., “le0”
    union {
  struct sockaddr ifru_addr;
  struct sockaddr ifru_dstaddr;
  struct sockaddr ifru_broadaddr;
  short ifru_flags;
  int ifru_metric;
  caddr_t ifru_data;
    }ifr_ifru;
};
#define ifr_addr  ifr_ifru.ifru_addr   // address
#define ifr_dstaddr  ifr_ifru.ifru_dstaddr  // otner end of p-to-p link
#define ifr_broadaddr ifr_ifru.ifru_broadaddr  // broadcast address
#define ifr_flags  ifr_ifru.ifru_flags   // flags
#define ifr_metric  ifr_ifru.ifru_metric  // metric
#define ifr_data  ifr_ifru.ifru_data   // for use by interface

//通用网络地址结构体
#include<sys/socket.h>
struct sockaddr {
 unsigned short sa_family;  //address family, AF_xxx
 char sa_data[14];    //14 bytes of protocol address
};

//IPV4网络地址结构体
#include<netinet/in.h>
struct sockaddr_in {
 short int sin_family;   //Address family
 unsigned short int sin_port; //Port number
 struct in_addr sin_addr;  //Internet address
 unsigned char sin_zero[8];  //Same size as struct sockaddr
};

//网络二进制地址结构体
#include<arpa/inet.h>
struct in_addr {
 unsigned long s_addr;
};

in_addr_t//网络二进制数格式, 与 struct in_addr 中的 s_addr 一致

#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

//将点分十进制地址 cp 转换为网络二进制数存入 inp
int inet_aton(const char *cp, struct in_addr *inp);

 inet_aton() converts the Internet host address  cp  from  the  standard/
 numbers-and-dots  notation into binary data and stores it in the struc-/
 ture that inp points to. inet_aton() returns non-zero if the address is/
 valid, zero if not.

//将网络二进制数转换为点分十进制
char *inet_ntoa(struct in_addr in);

 inet_ntoa() function converts the Internet host address in given in/
 network  byte  order to a string in standard numbers-and-dots notation./
 The string is returned in a statically allocated buffer,  which  subse-/
 quent calls will overwrite.


//将点分十进制地址 cp 转换为网络二进制数返回
in_addr_t inet_addr(const char *cp);

 inet_addr()  function  converts  the Internet host address cp from/
 numbers-and-dots notation into binary data in network byte  order.   If/
 the input is invalid, INADDR_NONE (usually -1) is returned.  This is an/
 obsolete interface to inet_aton(), described immediately above;  it  is/
 obsolete   because   -1  is  a  valid  address  (255.255.255.255),  and/
 inet_aton() provides a cleaner way to indicate error return.

//将点分十进制地址 cp 转换为网络二进制数返回
in_addr_t inet_network(const char *cp);

 inet_network() function extracts a number suitable for  use  as  an/
 Internet address in host byte order from the address cp in numbers-and-/
 dots notation.  If the input is invalid, -1 is returned.

//从地址返回主机地址部分的主机序列二进制数
in_addr_t inet_lnaof(struct in_addr in);

 inet_lnaof()  function  returns the local host address part of the/
 Internet address in.  The local host address is returned in local  host/
 byte order.

//从地址返回网络地址部分的主机序列二进制数
in_addr_t inet_netof(struct in_addr in);

 inet_netof() function returns the network number part of the Inter-/
 net Address in.  The network number is  returned  in  local  host  byte/
 order.

//根据网络地址和主机地址生成子掩码
struct in_addr inet_makeaddr(int net, int host);

 inet_makeaddr() function makes an Internet host address in network/
 byte order by combining the network number net with the  local  address/
 host in network net, both in local host byte order.
=============================================================*/

int main(int argc, char *argv[])
{
 int inet_sock;
 struct ifreq ifr;
 
 //建立套接字
 inet_sock = socket(AF_INET, SOCK_DGRAM, 0);
 
 //获得接口地址
 bzero(&ifr, sizeof(ifr));
 strcpy(ifr.ifr_name, "eth0");
 if (ioctl(inet_sock, SIOCGIFADDR, &ifr) < 0)
  perror("ioctl");
 printf("host:%s/n", inet_ntoa(((struct sockaddr_in*)&(ifr.ifr_addr))->sin_addr));
 //获得广播地址
 bzero(&ifr, sizeof(ifr));
 strcpy(ifr.ifr_name, "eth0");
 if (ioctl(inet_sock, SIOCGIFBRDADDR, &ifr) < 0)
  perror("ioctl");
 printf("broadcast:%s/n", inet_ntoa(((struct sockaddr_in*)&(ifr.ifr_addr))->sin_addr));
 
 return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值