1.IPv4套接口地址结构
IPv4套接口地址结构通常称为“网际套接字地址结构”,它以“sockaddr_in”命名,定义在头文件<netinet/in.h>中
struct sockaddr_in{
uint8_t sin_len; //整个sockaddr_in结构体的长度;
sa_family_t sin_family; //指定地址族,必须设定为AF_INET(ipv4地址族);
in_port_t sin_port; //端口,2B;
struct in_addr sin_addr; //IPv4的地址,4B;
char sin_zero[8]; //暂不使用,一般为0,8B;
};
struct in_addr {
uint32_t s_addr; //IP地址(网络字节序);
};
2.通用地址结构
struct sockaddr{
uint8_t sin_len; //整个sockaddr结构体的长度;
sa_family_t sin_family; //指定地址族,必须设定为AF_INET(ipv4地址族);
char sa_data[14]; //由sin_family决定它的形式,14B;
};
3.网络字节序
3.1字节序
3.1.1大端字节序:最高有效位存储于最低内存地址,最低有效位存储于最高内存地址;
3.1.2小端字节序:最高有效位存储于最高内存地址,最低有效位存储于最低内存地址;
比如:0x12345678
大端字节序存储:12 34 56 78
小端字节序存储:78 56 34 12
3.2主机字节序:不同的主机有不同的字节序,如x86为小端字节序;
3.3网络字节序:网络字节序规定为大端字节序;
4.字节序转换函数(h:host,n:networks,s:short,l:long;)
#include <netinet/in.h>
uint32_t htonl(uint32_t hostlong); //4个字节的整数,由主机字节序转换为网络字节序;
uint16_t htons(uint16_t hostshort); //2个字节的整数,由主机字节序转换为网络字节序;
uint32_t ntonl(uint32_t netlong); //4个字节的整数,由网络字节序转换为主机字节序;
uint16_t ntons(uint16_t netshort); //2个字节的整数,由网络字节序转换为主机字节序;
5.地址转换函数
#include <arpa/inet.h>
int inet_aton(const char *cp, struct in_addr *inp); //将点分十进制的字符串转换为32位的整数(网络序);
uint32_t inet_addr(const char *cp); //将点分十进制的字符串转换为32位的整数(网络序);
char *inet_ntoa(struct in_addr in); //将32位的整数转为点分十进制的字符串;
int inet_pton(int family, cons char*src, void* dst); //将点分十进制字符串转为网络序的整数,成功返回1,非法字符串返回0,family非法返回-1;将点分十进制字符串转为网络序的整数,成功返回1,非法字符串返回0,family非法返回-1;
将网络序整数转为点分十进制字符串,size是目标存储单元的大小,如下可取值
include <netinet/in.h>
#define INET_ADDRSTRLEN 16 /* for IPv4 dotted-decimal */
#define INET6_ADDRSTRLEN 46 /* for IPv6 hex sring */
6.套接字类型
6.1流式套接字(SOCK_STREAM):提供面向连接的/可靠的数据传输服务,数据无差错,无重复的发送,且按发送顺序接收;
6.2数据报式套接字(SOCK_DGRAM):提供无连接服务,不提供无错保证,数据可能丢失或重复,并且接收顺序混乱;
6.3原始套接字(SOCK_RAW):
7.实验
#include <iostream>
#include <string>
#include <netinet/in.h> //sockaddr_in, sockaddr, htonl, ntonl
#include <arpa/inet.h> //inet_aton, inet_addr, inet_aton
#include <stdio.h>
using namespace std;
int main() {
unsigned int x = 0x12345678;
printf("values of x: %x\n", x);
unsigned char *p = (unsigned char*)&x;
printf("X86 save byte by network byte order: ");
printf("%x %x %x %x\n",p[0],p[1],p[2],p[3]); //order by host, print:78 56 34 12
unsigned int y = htonl(x); //order turn host to network
printf("x turn to network byte order(y): %x\n", y);
unsigned int z = ntohl(y);
printf("y turn to host byte order(z): %x\n", z);
const char *ip1 = "192.168.1.1";
uint32_t addr = inet_addr(ip1);
printf("%s turn to uint32(host order) : %x\n",ip1, ntohl(addr));
struct in_addr ipaddr;
ipaddr.s_addr = addr;
char *ip2 = inet_ntoa(ipaddr);
printf("%x turn to string : %s\n", htonl(addr), ip2);
struct in_addr ipaddr2;
inet_aton(ip1, &ipaddr2);
printf("%s turn to uint32_t: %x(network order)\n", ip1, ipaddr2.s_addr);
return 0;
}