struct sockaddr和struct sockaddr_in
Socket.h文件中struct sockaddr
的定义如下所示:
/* * Structure used by kernel to store most * addresses. */ struct sockaddr { u_char sa_len; /* total length */ sa_family_t sa_family; /* address family */ char sa_data[14]; /* actually longer; address value */ };
In.h文件中struct sockaddr_in
的定义如下所示:
struct in_addr { in_addr_t s_addr; //in_addr_t为无符号int类型,4个字节 }; /* * Socket address, internet style. */ struct sockaddr_in { u_char sin_len; u_char sin_family; u_short sin_port; struct in_addr sin_addr; char sin_zero[8]; };
可以看到struct sockaddr
和struct sockaddr_in
都是16个字节,而且是一一对应的关系。所以,这两个结构体的转化使用强制类型转化就可以。
在堆叠项目的rpc设计中,则可以使用char tmp[16]
的字符数组存放这两个结构体,用于rip路由表的同步。
下面是结构体struct in_addr
的应用实例,一个UINT32的IP地址,需要转化为a.b.c.d的字符串格式。
UINT32 ip = 0x010101010; char ipAddr[20] = {0}; struct in_addr iaddr; iaddr.s_addr = ip; inet_ntoa_b (iaddr, ipAddr);
OSPF中字符串转化为IP地址或者数字
OSPF中的区域ID既可以是数字,又可以是IP地址形式(a.b.c.d)。cli输入该字符串之后,需要获取其数值,存放到UINT 32的整型变量中。
第一次撰写的代码如下,IP地址字符串和数字字符串全部手动解析。
/*! *\fn STATUS ospfStr2int() *\brief convert the string to int *\details the string must be ip address or pure int string *\param[in] * *\note *\author NieYong <NieYong@tp-link.net> */ STATUS ospfStr2int(char* p,UINT32 * ipAddr) { UINT8 flg = 0; UINT8 nLen; INT16 nTemp = 0; UINT8 nPosition = 0; UINT8 cIp[4]; char *pszIp; UINT32 num = 0; if (NULL != p) { while (*p != '\0' && isspace((int)*p) != 0) { p++; } } /* printf("ospfStr2int:%s\n",p); */ pszIp = p; nLen = strlen(pszIp); if((NULL == pszIp) ||(nLen > IP_ADDRESS_LENGTH)) { return ERROR; } /* first,we check if the string is int number string */ while(flg != 1 && *pszIp != '\0') { switch(*pszIp) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': num = num * 10 + *pszIp - '0'; break; default: flg = 1; break; } pszIp++; } if(flg != 1) { /* we're here,meant the ip address string is right */ * ipAddr = num; /* printf("ospfStr2int:%d\n",* ipAddr); */ return OK; } /* if the check above failed,we should check if the string is ip address sting secondly */ pszIp = p; while(*pszIp != '\0') { switch(*pszIp) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': nTemp = nTemp * 10 + *pszIp - '0'; if(nTemp > 255) { return ERROR; } break; case '.': /* except case : 192..0.1 */ if( '.' == *(pszIp + 1)) { return ERROR; } /* except case : 192.168.0.1.5 */ if(3 == nPosition) { return ERROR; } //store the ipaddress cIp[nPosition] = nTemp; nPosition ++; nTemp = 0; break; default: return ERROR; break; } pszIp++; } if(nPosition == 3) { /* we're here,meant the ip address string is right */ cIp[nPosition] = nTemp; *ipAddr = (cIp[0]<<24) + (cIp[1]<<16) + (cIp[2]<<8) + cIp[3]; /* printf("ospfStr2int:%d\n",* ipAddr); */ return OK; } else { return ERROR; } }
修改之后,对于ip地址类型字符串的解析直接使用函数inet_aton(),这样可以避免不少问题。代码如下:
/*! *\fn STATUS swOspfStr2int() *\brief convert the string to int *\details the string must be ip address or pure int string *\param[in] * *\note *\author NieYong <NieYong@tp-link.net> */ STATUS swOspfStr2int(char* p,UINT32 * ipAddr) { UINT8 flg = 0; UINT8 nLen; INT16 nTemp = 0; UINT8 nPosition = 0; UINT8 cIp[4]; char *pszIp; UINT32 num = 0; struct in_addr inAddr; if (NULL != p) { while (*p != '\0' && isspace((int)*p) != 0) { p++; } } OSPF_DBG_PRINT("swOspfStr2int:%s\n",p); pszIp = p; nLen = strlen(pszIp); if((NULL == pszIp) ||(nLen > IP_ADDRESS_LENGTH)) { return ERROR; } /* first check if the string is ip dot notation style */ if(inet_aton(pszIp,&inAddr)) { /* the string is dot notation style */ ipAddr = inAddr.s_addr; return OK; } /* if the string is not dot notation,we should check if * the string is int number string. */ while(flg != 1 && *pszIp != '\0') { switch(*pszIp) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': num = num * 10 + *pszIp - '0'; break; default: flg = 1; break; } pszIp++; } if(flg != 1) { /* we're here,meant the ip address string is right */ * ipAddr = num; OSPF_DBG_PRINT("ospfStr2int:%d\n",* ipAddr); return OK; } else { return ERROR; } }