套接字编程简介【1】
- 套接字地址结构
- IPV4套接字
- 32位IPv4地址结构体
-
1 struct in_addr{ 2 in_addr_t s_addr; //32位 IP 地址 网络字节序 3 };
- IPv4套接字结构体
-
1 struct sockaddr_in{ 2 uint8_t sin_len; 3 sa_family_t sin_family; //套接字地址结构的地址族 4 in_port_t sin_port; //端口号 5 struct in_addr sin_addr; //IPv4地址 6 char size_zero[8]; 7 }
注意:当将IPv4地址用作参数时候,要正确的使用IPv4地址,搞清楚是serv.sin_addr还是serv.sin_addr.s_addr。
- IPV6套接字
- 128位IPv6地址
-
1 struct in6_addr{ 2 unit8_t s6_addr[16]; //128-bit IPv6 address 网络字节序 3 }
- IPv6地址结构体
-
1 #define SIN6_LEN 2 3 struct sockaddr_in6{ 4 uint8_t sin6_len; 5 sa_family_t sin6_family; 6 in_port_t sin6_port; 7 uint32_t sin6_flowinfo;//undefined 8 struct in6_addr sin6_addr; 9 unit32_t sin6_scope_id;//最常见的是链路地址索引 10 }
- 通用套接字
- 旧版本
- 新版本
-
1 struct sockaddr_storage { 2 uint8_t ss_len; //本结构体的长度 3 sa_family_t ss_family; //协议地址族 4 }
注意:编写协议无关程序时候用通用套接字,直接记住用新版的通用套接字的原因如下:1、如果系统支持的任何套接字地址结构有对齐要求,那么sockaddr_storage可以满足最苛刻的对齐要求;2、sockaddr_storage足够大,可以容纳系统支持的任何套接字结构。
- 字节排序函数 :网络字节序与主机字节序之间的相互转换
-
1 #include <netinet/in.h> 2 //主机字节序-->网络字节序 3 uint16_t htons(uint16_t host16bitvalue); 4 uint32_t htonl(uint32_t host32bitvalue); 5 //网络字节序-->主机字节序 6 uint16_t ntohs(uint16_t net16bitvalue); 7 uint32_t ntohl(uint32_t net32bitvalue);
- 字节操纵函数 :不对数据解释,也不假设字符串以\0结尾,只是进行单纯的内存操作(赋值、复制、比较)
- 来自Berkelery的函数
-
//来自伯克利的函数 #include <strings.h> void bzero(void *dest,size_t nbytes); /*把目标字节串中指定书目的字节置为0*/ void bcopy(const void *src,void *dest,size_t nbytes);/*将指定数目的字节从源字节串复制到目标字节串*/ void bcmp(const void *ptr1,const void *ptr2,size_t nbytes);/*比较两个任意的字节串,相同返回0*/
-
- ANSI C提供的函数
1 #include<strings.h> 2 void *memset(void *dest,int c,size_t len); 3 void *memcpy(void* dest,const void *src,size_t nbytes); 4 int memcmp(const void *ptr1,const void *ptr2,size_t nbytes);
- memset将目标字节串指定数目的字节置为值c
- memcpy类似与bopy(注意:当源字节串与目标字节串重叠时,bcopy能够正确处理,但是memcpy操作结果不可知,如果仍然只能用ANSI C提供的函数,这时候应该考虑memmove函数。详见:memcpy和memmove比较)
- memcmp比较两个任意的字节串,若相同则返回0