精简版inet_addr
CooCox Cedar@Wuhan
说明:
今天在移植代码的时候,需要一个客户端WiFiClientConnect函数,该函数的一个参数为服务器地址,第二个为端口。
其中服务器的地址可以是主机地址(如: www.baidu.com ),也可以是IP地址(如:192.168.2.71)。
官方的WIFI驱动是C++重载函数写的,可以根据不同的输入格式来调用对应的函数,C中没有重载,只有手工解析,解决方法有3个:
1:分别采用2个函数,比如提供WiFiClientConnectVia 和Host WiFiClientConnectViaIP两个函数,供用户调用
2:像Arduino WiFi驱动接口那样,使用一个函数,但增加一个入口参数,用于指明服务器地址类型
3:符合Arduino 官方WIFI的调用习惯,用一个WiFiClientConnect函数,用户只需输入HOST或IP即可,解析的问题,交给函数内部来处理如 WiFiConnect( "www.baidu.com", 80);WiFiConnect( "192.168.2.71", 80)
最终为了方便用户,采用了最后一个方案,这样用户可以更加方便的使用WIFI
我们需要在内部识别出是否是有效的IP地址,如果是的话,则转换为网络地址,这样就需要一个识别和转换函数IPToNetAddr。
IPToNetAddr将传入的IP地址解析成网络格式,比如将“192.168.2.71”分割成4个10进制的数字,存到数组里面
在Q群问了网友,有人说inet_addr符合要求,找到对应源码后,发现它考虑的情况太多了,支持各种进制的数字,而我们这里,只需要支持10进制就ok,网上搜了一下,貌似没人写过这函数,所以还是自己动手写一个吧
要求:
1:能识别出输入IP字符串是否有效,有效则返回0,无效则返回-1
2:输入错误的IP地址,函数不损坏存放结果的数组
错误的IP例子:
1:
子项过大:每个子项应小于255。下面的IP地址第一个子项为1921,大于255
1921.108.2.71
2:
子项过多:应有4个子项,由3个.号分隔,下面的IP地址有5个子项
192.168.2.1.2
测试代码如下:
int main(void)
{
int retv = 0;
//目标IP地址字符串
char IP_OK[] = "192.168.002.071";
char IP_ERROR_1[] = "1921.108.2.71";
char IP_ERROR_2[] = "192.168.2.1.2";
char IP_ERROR_3[] = "293.168.2.1.2";
char IP_ERROR_4[] = "193.168.2.1.300";
//存储结果数组
uint8_t result[4] = {0, 0, 0, 0};
retv = IPToNetAddr(IP_OK, result);
if(-1 == retv)
{
printf("Test Failure\r\n");
while(1);
}
retv = IPToNetAddr(IP_ERROR_1, result);
if(0 == retv)
{
printf("Test Failure\r\n");
while(1);
}
retv = IPToNetAddr(IP_ERROR_2, result);
if(0 == retv)
{
printf("Test Failure\r\n");
while(1);
}
retv = IPToNetAddr(IP_ERROR_3, result);
if(0 == retv)
{
printf("Test Failure\r\n");
while(1);
}
retv = IPToNetAddr(IP_ERROR_3, result);
if(0 == retv)
{
printf("Test Failure\r\n");
while(1);
}
printf("Test OK, Press any key to exit\r\n");
getchar();
return (0);
}
|
完整代码如下:
CODE:
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
//#include <stdint.h>
#include <string.h>
typedef unsigned char uint8_t;
typedef signed char int8_t;
typedef unsigned int uint32_t;
typedef signed int int32_t;
int IPToNetAddr(char * IPStr, uint8_t * NetAddr);
int main(void)
{
int retv = 0;
//目标IP地址字符串
char IP_OK[] = "192.168.002.071";
char IP_ERROR_1[] = "1921.108.2.71";
char IP_ERROR_2[] = "192.168.2.1.2";
char IP_ERROR_3[] = "293.168.2.1.2";
char IP_ERROR_4[] = "193.168.2.1.300";
//存储结果数组
uint8_t result[4] = {0, 0, 0, 0};
retv = IPToNetAddr(IP_OK, result);
if(-1 == retv)
{
printf("Test Failure\r\n");
while(1);
}
retv = IPToNetAddr(IP_ERROR_1, result);
if(0 == retv)
{
printf("Test Failure\r\n");
while(1);
}
retv = IPToNetAddr(IP_ERROR_2, result);
if(0 == retv)
{
printf("Test Failure\r\n");
while(1);
}
retv = IPToNetAddr(IP_ERROR_3, result);
if(0 == retv)
{
printf("Test Failure\r\n");
while(1);
}
retv = IPToNetAddr(IP_ERROR_4, result);
if(0 == retv)
{
printf("Test Failure\r\n");
while(1);
}
printf("Test OK, Press any key to exit\r\n");
getchar();
return (0);
}
int IPToNetAddr(char * IPStr, uint8_t * NetAddr)
{
uint32_t _IP[4] = {0, 0, 0, 0};
uint8_t cnt = 0;
uint8_t idx = 0;
char _str = NULL;
//检查IP和接收缓存区是否有效
if(IPStr == NULL || NetAddr == NULL)
{
return (-1);
}
while((_str = *IPStr++) != NULL)
{
if(_str == '.')
{
//清空计数器,该计数器最大值为3
cnt = 0;
if(_IP[idx] > 255)
{
return (-1);
}
idx = idx + 1;
}
else if(_str >= '0' && _str <= '9') //检查是否为有效字符 '0' --> '9'
{
if(cnt++ < 3 && idx <= 3)
{
_IP[idx] = (10 * _IP[idx]) + (_str - '0');
}
else
{
return (-1);
}
}
else
{
return (-1);
}
}
if(_IP[idx] > 255)
{
return (-1);
}
//复制数据到结果缓存区
NetAddr[0] = (uint8_t)_IP[0];
NetAddr[1] =
(uint8_t)
_IP[1];
NetAddr[2] =
(uint8_t)
_IP[2];
NetAddr[3] =
(uint8_t)
_IP[3];
return (0);
}
|
英文版本:
static int IPToNetAddr(char * IPStr, uint8_t * NetAddr)
{
uint32_t _IP[4] = {0, 0, 0, 0};
uint8_t cnt = 0;
uint8_t idx = 0;
char _str = NULL;
// Check input paramters vaild
if(IPStr == NULL || NetAddr == NULL)
{
return (-1);
}
while((_str = *IPStr++) != NULL)
{
if(_str == '.')
{
// Clear the count, cnt MUST <= 3
cnt = 0;
if(_IP[idx] > 255)
{
return (-1);
}
idx = idx + 1;
}
else if(_str >= '0' && _str <= '9') // '0' --> '9'
{
if(cnt++ < 3 && idx <= 3)
{
_IP[idx] = (10 * _IP[idx]) + (_str - '0');
}
else
{
return (-1);
}
}
else
{
return (-1);
}
}
if(_IP[idx] > 255)
{
return (-1);
}
// Copy Buffer to user space
NetAddr[0] = (uint8_t)_IP[0];
NetAddr[1] = (uint8_t)_IP[1];
NetAddr[2] = (uint8_t)_IP[2];
NetAddr[3] = (uint8_t)_IP[3];
return (0);
}
|
#本文结束#