1 IP地址和端口号
1.1 IP为网络协议的简称,为了收发网络数据分配给计算机的值。端口号则为区分程序中创建的套接字而分配给套接字的序号。 IPV4 4字节地址族 IPV6 16字节地址族
1.2 IPv4 地址可以分为四种类型 A类:1字节网络ID,3字节主机ID 首字节范围:0-127 B类:2字节网络ID,2字节主机ID 首字节范围:128-191 C类:3字节网络ID,1字节主机ID 首字节范围:192-223 D类:4字节网络ID
数据传输时,通过网络Id找到网络地址,之后通过主机ID找到该网络下的主机地址
1.3端口号 端口号在同一操作系统下区分不同套接字设置,无法将同一端口号分配给不同套接字。 端口号由16位组成,端口号的取值范围为:0-2^16-1,0-1023为指定端口号,一般分配给特定程序。TCP套接字和UDP套接字不共用端口号。
2地址信息表示
2.1 地址信息采用结构体表示:
struct sockaddr_in
{
sa_family_t sin_family;
uint16_t sin_port;
struct in_addr sin_addr;
char sin_zero[8];
}
struct in_addr
{
In_addr_t s_addr;
}
2.2 uint16_t,in_addr,sa_family_t等类型为POSIX定义的类型。 uint16_t头文件为:sys/types.h sa_family_t头文件为:sys/socket.h in_addr_t头文件为:netinet/in.h sin_family为地址族信息: AF_INET:IPv4网络协议中使用的地址族 AF_INET6:IPv6网络协议中使用的地址族 AF_LOCAL:本地通信中采用的UNIX协议的地址族
成员sin_port 位16位的无符号整数,以网络字节序保存! 成员sin_addr in_add_r为32位整数 成员sin_zero无特殊含义,用来保持结构体sockaddr_in的大小与sockaddr结构体保持一致,而插入的成员,全部填充位0
2.3 bind和sockaddr
struct socketaddr_in serv_addr;
if(bind(serv_sock,(struct sockaddr *)&serv_addr,sizeof(serv_addr))==-1)
error_handling("bind()error");
第一个参数为socket ,第二个参数为地址信息
struct sockaddr{
sa_family_t sin_family;
char sa_data[14];
}
sa_data中存储地址IP和端口号,对于IPv4地址,IP地址为32位,4字节,端口号16位,2字节,此时对应上面sin_zero[8]为8个字节,刚好为sa_data的大小,14字节。 2.4 网络字节序 CPU保存数据的形式为:大端序和小端序。 大端序:高位字节放在低位地址。 小端序:高位字节放在高位地址。 网络字节序统一采用大端序。 字节序转换: h:主机字节序 n:网络字节序 s:short型数据 l:long型数据(Linux中long型数据占用4个字节) htons:将short型数据从主机字节序转换为网络字节序
unsigned short host_port=0x1234;
unsigned short net_port;
unsigned long host_addr=0x12345678;
unsigned long net_addr;
net_port=htons(host_port);
net_addr=htonl(host_addr);
注:实际使用中,除了向sockaddr_in结构体变量填充数据,其他情况无需考虑字节序问题,均为自动转换。
3网络地址初始化和分配
3.1字符串信息转换为网络字节序的整数型 对于IP地址,常用的为点分十进制表示法,而不是整型数据表示法,可以通过某个函数来实现将字符串形式的IP地址转换为32位的整数型数据。
#include<arpa/inet.h>
in_addr_t inet_addr(const char* string);
char *addr1="1.2.3.4";
unsigned long conv_addr=inet(addr1);
该函数不仅可以将IP地址转换成32位整数型,而且可以检测无效的IP地址
inet_aton函数与inet_addr函数功能相同,但其利用到了in_addr结构体,因此使用频率更高
#include<arpa/inet.h>
int inet_aton(const char* string,struct in_addr* addr);
char *addr="127.232.124.79";
struct sockaddr_in addr_inet;
inet_aton(addr,&addr_inet.sin_addr);
3.2 网络字节序整数型IP地址转换位字符串形式
inet_ntoa函数
#include<arpa/inet.h>
char* inet_ntoa(struct in_addr adr);
struct sockaddr_in addr1;
char* str_ptr;
char str_arr[20];
addr1.sin_addr.s_addr=hton(0x1020304);
str_ptr=inet_ntoa(addr1.sin_addr);
strcpy(str_arr,str_ptr);
3.3 网络初始化:
struct socket_in addr;
char* serv_ip="211.217.168.13";
char* serv_port="9190";
memset(&addr,0.sizeof(addr));
addr.sin_family=AF_INET;
addr.sin_addr.s_addr=inet_addr(serv_ip);
addr.sin_port=htons(atoi(serv_port));
|