【网络编程】学习笔记--03 地址族与数据序列
为什么要设定端口号:
端口号就是在统一操作系统内区分不同的套接字所设置的。
地址信息的表示:
回顾《学习笔记--01》中的bind函数
#include<sys/socket.h> int bind(int sockfd,struct sockaddr *myaddr,socklen_t addrlen)
接下来我们会讲解第二个参数sockaddr结构体和与他类似的sockaddr_in结构体
关于sockaddr_in结构体:
struct sockaddr_in { sa_family_t sin_family; //地址族(address family) unit16_t sin_port; //16位TCP/UDP端口 struct in_addr sin_addr; //32位IP地址 char sin_zero[8]; //不使用 } 其中该结构体中第3个提到的另一个结构体in_addr定义如下: struct in_addr { in_addr_t s_addr; //32位IPv4地址 }
从之前介绍的代码也可以看出,sockaddr_in结构体变量地址值将以如下方式传递给bind函数,重点关注参数传递和类型转换部分代码。
struct sockaddr_in serv_addr; .... if(bind(serv_sock,(struct sockaddr *)&serv_addr,sizeof(serv_addr))==-1) error_handling("bind error!"); ....
此处重要的是第2个参数的传递。实际上,bind函数的第2个参数期望得到sockaddr结构体变量地址值,包括地址族、端口号、IP地址等。从下列代码也可看出,直接向sockaddr结构体填充这些信息会带来麻烦
struct sockaddr { sa_family_t sin_family; //地址族 char sa_data[14]; //地址信息 }
此结构体中,sa_data保存的信息中需包含IP地址和端口号,其余部分填充0。而这对于包含地址信息来说非常麻烦,继而就有了新的结构体sockaddr_in。若按照之前的讲解填写sockaddr_in结构体,则将生成符合bind函数要求的字节流。最后转换为sockaddr型的结构体变量,再传递给bind函数即可。
字节序转换:
unsigned short htons unsigned short ntohs unsigned long htonl unsigned long ntohl htons中的h代表主机(host)的字节序 htons中的n代表网络(network)的字节序
另外一个inet_addr函数:
#include<arpa/inet.h> in_addr_t inet_addr(const char *string) | |-成功时返回32位大端序整数型值,失败时返回INADDR_NONE |-比如“211.214.107.99”从点分十进制变成32位整数型 |-该函数还可以检测无效的IP地址
而接下来我们要提到一个函数叫inet_aton函数,这个函数与inet_addr函数功能上完全相同,也将字符串形式IP地址转换为32位网络编程字节序整数并返回。只不过该函数利用了in_addr结构体,且其使用频率更高。
#include<arpa/inet.h> int inet_aton(const char *string,struct in_addr *addr) | |-成功时返回1,失败时返回0 |-string:含有需转换的IP地址信息的字符串地址值 |-adr:将保存转换结果的in_addr结构体变量的地址值
前ICPC算法竞赛退役选手|现摸鱼ing