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;
}
}