【网络编程】学习笔记--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结构体变量的地址值

 

posted @ 2021-11-09 13:39  Anonytt  阅读(40)  评论(0编辑  收藏  举报