Unix网络编程【2】-套接口操作函数
本博客参考自《Unix网络编程卷1》
套接字操作函数
1.字节排序函数
一个16位的整数,由两个字节组成。它在计算机中有两种存储方式:1.将低字节作为起始地址-小端序。2.将高字节作为起始地址-大端序。
MSB(most significant bit):做高有效位。LSB(least significant bit)-最低有效位
一般的intelCPU都是按照小端序存储数据,而网络通信中一般要求大端序。可用下面的程序判断系统的字节序。
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv)
{
union {
short s;
char c[sizeof(short)];
} un;
un.s = 0x0102;
if (sizeof(short) == 2) {
if (un.c[0] == 1 && un.c[1] == 2)
printf("big-endian\n");
else if (un.c[0] == 2 && un.c[1] == 1)
printf("little-endian\n");
else
printf("unknown\n");
} else
printf("sizeof(short) = %d\n", sizeof(short));
exit(0);
}
本人Ubuntu系统运行的结果:
对上述程序的说明:程序采用union结构共享内存,通过使用不同的方式解读内存,获得主机的大端、小端信息。
在编写网络通信程序时,通常需要在大端和小端序之间转换,以下几个函数可以实现这些功能
Ubuntu:/usr/include/netinet/in.h
#include <netinet/in.h>
uint16_t htons(uint16_t host16bitvalue);
uint32_t htonl(uint32_t host32bitvalue);
uint16_t ntohs(unit16_t net16bitvalue);
uint32_t ntohl(uint32_t net32bitvalue);
其中h-host,n-network,s-short,l-long。其中前两个函数传入主机字节返回网络字节。后两个函数传入网络字节返回主机字节。s结尾代表对16位端口操作,l结尾代表对32位IP地址操作。
2.字节操纵函数
字节操纵函数主要的作用是对指针指向的多字节内存进行清零、拷贝和比较的操作。这些函数著有有两类:一类是以b开头的,一类是以mem开头的。
Ubuntu:/usr/include/strings.h
#include<strings.h>
void bzero(void *dest,size_t ntytes);
void bcopy(const void*src,void*dst,size_t nbytes);
int bcmp(const void* ptr1, const void* ptr2,size_t nbytes)
bzero-把目标字节串中指定数目的字节置0.
bcopy-将指定数目的字节从源字节串移到目标字节串。
bcmp-比较两个任意字节串,相同返回0,否则返回非0.
Ubuntu:/usr/include/string.h
#include <string.h>
void *memset(void *dest,int c,size_t len);
void *memcpy(void *dest, const void *src,size_t nbytes);
int memcmp(const void *ptrl,const void *ptr2,size_t nbytes)
memset-将目标字节串指定数目的字节置为c。
memcpy-类似与bcopy,不过两个指针的顺序相反。当源字节串与目标字节串重叠时,需要用memmove代替memcpy。
memcmp-比较两个任意字符串,ptr1>ptr2返回大于0。ptr1 == ptr2 返回0。ptr1 < ptr2返回小于0。字节比较从第一个字节开始,直到出现第一个不等的字节。
3.IP地址转换函数
在编写网络程序时,通常需要在点分十进制串(127.0.0.1)与网络字节二进制之间转换,下面介绍进行转换的函数
IPv4版本
Ubuntu:/usr/include/arpa/inet.h
#include <arpa/inet.h>
int inet_aton(const char *strptr,struct in_addr *addrptr);
in_addr_t inet_addr(const char *strptr);
char *inet_ntoa(struct in_addr inaddr);
inet_aton-将strptr所指C字符串转换成一个32位网络字节序二进制值,通过addrptr来存储。成功返回1,否则返回0.
inet_addr-将点分十进制字符串转换为32位网络字节序二进制,通过返回值返回。INADDR_NONE=255.255.255.255用于指示错误。这就意味着255.255.255.255不能通过该函数处理。此函数现在基本已经废弃。
inet_ntoa-将一个32位的网络字节序二进制IPv4转换成相应的点分十进制数串。
IPv4和IPv6通用版本
Ubuntu:/usr/include/arpa/inet.h
#include <arpa/inet.h>
int inet_pton(int family,const char *strptr,void *addrptr);
const char *inet_ntop(int family,const void *addrptr,char *strptr,size_t len);
函数中p和n分别代表presentation和numeric。其中family参数有两个选项AF_INET和AF_IENT6,如果以不支持的协议族调用,函数会将errno置为EAFNOSUPPORT.
inet_pton-将strptr指针所指定的字符串,转换为对应的二进制结果并存放在addrptr指针所指的内存区域。若成功返回1,输入格式无效返回0,出错返回-1.
inet_ntop-将数值格式(addrptr)转换为对应的表达格式(strptr)。len用于指定目标存储单元大小。如果len过小,errno会被置为ENOSPC。strptr不可以为空指针,调用者需要分配内存。调用成功这个指针就是函数返回值。
对5个转换函数的总结
IPv6地址一共128位,16位之间有个“:”。
IPv4兼容的IPv6或者映射的IPv6,前6个16位正常表达,后2个16位表达成IPv4的表达格式。
上一篇: kurento-media-server opencv 模块的创建
下一篇: Java数字类
推荐阅读