好久没更新博客了,2011年了,也得有个开端才行,所以特意对linux应用编程做了一些总结,现晒出来,希望能给大家一点参考,同时也作为自己的备忘录,何乐而不为之................(学海无涯)-------------------------------------------water
网络编程(1)
1服务端的初始化
下面是一个tcp和udp的server端初始化的通用封装函数,来自于APUE。非常的好用。
其包括创建套接字,bind ,listen(udp省去)
/********************************************************************
* 函数名: initserver
* 功 能: 初始化网络服务器,包括创建套接字,listen, bind等
* 版本 : come from APUE
********************************************************************/
int
initserver(int type, const struct sockaddr *addr, socklen_t alen,int qlen)
{
int fd, err;
int reuse = 1;
if ((fd = socket(addr->sa_family, type, 0)) < 0)
return(-1);
/* 使得重复使用本地地址与套接字进行绑定 */
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse,
sizeof(int)) < 0) {
err = errno;
goto errout;
}
if (bind(fd, addr, alen) < 0) {
err = errno;
goto errout;
}
//如果是udp的server则不需要用到listen
if (type == SOCK_STREAM || type == SOCK_SEQPACKET) {
if (listen(fd, qlen) < 0) {
err = errno;
goto errout;
}
}
return(fd);
errout:
close(fd);
errno = err;
return(-1);
}
例如TCP的服务端可以这样调用:
struct sockaddr_in serv_addr, client_addr;
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(NET_PORT); //18020
serv_addr.sin_addr.s_addr = INADDR_ANY;
bzero(&(serv_addr.sin_zero), 8);
/*建立socket连接*/
if( (socketd = initserver(SOCK_STREAM, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr),10)) >= 0 )
{
Accept().......
Receive()..........
}
Tcp与udp的编程区别
Tcp与udp的区别就是前者必须在服务端与客户端建立连接的基础上进行,即其server端必须有accept,而其client端必须connect主机。这样链接后双方便可用rev(),send()函数了,不一定要用recvfrom(),sendto(),因为双方的地址都是知道了的。而UDP则相反,在通信之前无需建立连接,所以要用recvfrom(),sendto(),其中的参数指定对方的地址。
下面总结下网络编程中值得注意的地方:
1数据存储顺序的转换:(h:host,n:network,s:short)
Htons(),ntohs(),htonl,ntohl()
如在设置端口时
serv_addr.sin_port = htons(18020);
必须把端口号18020转换成网络数据格式(大端),否则出错。我们无需知道主机的字节序,因为系统会有相关的宏去判断,确定htons()函数中是否真的去进行转换了。
2地址格式的转换:
1)Ip地址点分十进制字符串(“用户习惯的如“192.168.14.34”)与二进制转换(网络传输使用的)函数:
Ipv4:inet_aton(),inet_ntoa(),inet_addr()
Ipv4,ipv6兼容:inet_pton(),inet_ntop()
个人喜欢用IP4的前两个函数,调用的参数方便些。
2)物理地址字符串格式与网络二进制格式转换
ether_ntoa()
3几个字符串格式地址与数组存储格式的转换函数(自己写的);
/********************************************************************
* 函数名: ip_to_str
* 参数名: char *ip_strin)
unsigned char *ip_addrout)
*
* 返回值: no
* 功 能: 点十进制的字符串转成ip数组
* 版本 : water-2010-07-08--first
********************************************************************/
void str_to_ip(unsigned char *ip_str, unsigned char *ip_addr)
{
unsigned char tmp;
unsigned char *ip = ip_str;
while((*ip) != '\0')
{
tmp = 0;
while((*ip) != '.' && (*ip) != '\0')
{
tmp *= 10;
tmp += *ip -'0';
ip++;
}
if ( (*ip) == '.')
{
ip++;
*ip_addr = tmp;
ip_addr++;
}
}
*ip_addr = tmp;
}
/********************************************************************
* 函数名: str_to_mac
* 参数名: char *mac_str in)
unsigned char *mac_addr out)
*
* 返回值: no
* 功 能: 冒号16进制的字符串转成mac数组
* 版本 : water-2010-07-08--first
********************************************************************/
void str_to_mac(unsigned char *mac_str, unsigned char *mac_addr)
{
unsigned char tmp;
unsigned char *mac = mac_str;
while((*mac) != '\0')
{
tmp = 0;
while((*mac) != ':' && (*mac) != '\0')
{
tmp *= 16;
if(*mac >='0' && *mac <= '9')
tmp += *mac -'0';
if(*mac >= 'a' && *mac <= 'f')
tmp = tmp + 10 + *mac - 'a';
if(*mac >= 'A' && *mac <= 'F')
tmp = tmp +10 +*mac - 'A';
mac++;
}
if ( (*mac) == ':')
{
mac++;
*mac_addr = tmp;
mac_addr++;
}
}
*mac_addr = tmp;
}
/********************************************************************
* 函数名: ip_to_str
* 参数名: char *src in)
unsigned char *ip_str out)
*
* 返回值: no
* 功 能: ip数组转点十进制字符串
* 版本 : water-2010-07-08--first
********************************************************************/
void ip_to_str(unsigned char *ip_str, unsigned char *src)
{
sprintf(ip_str,"%d.%d.%d.%d",*(src), *(src+1), *(src+2), *(src+3));
}
/********************************************************************
* 函数名: mac_to_str
* 参数名: char *src in)
unsigned char *mac_str out)
*
* 返回值: no
* 功 能: mac数组转":16"进制字符串
* 版本 : water-2010-07-08--first
********************************************************************/
void mac_to_str(unsigned char *mac_str, unsigned char *src)
{
sprintf(mac_str,"%x:%x:%x:%x:%x:%x",*(src), *(src+1), *(src+2), *(src+3),*(src+4),*(src+5));
}
用户235394 2011-3-3 21:15