sockaddr和sockaddr_in结构体、以及inet_ntoa()和inet_addr()函数的用法

    在网络通讯程序中会用到sockaddr和sockaddr_in这两个结构体,下面对这两个结构体进行一下分析。

一、  sockaddr和sockaddr_in

  struct sockaddr 这个结构体是在<<sys/socket.h>>头文件中定义的。结构体的定义如下:

struct sockaddr 
{  
	sa_family_t sin_family;	        //地址族
	char sa_data[14]; 		//14字节,包含套接字中的目标地址和端口信息               
};

这个结构体中定义了地址族和14个字节的数据,数据中包含套接字中的目标地址和端口信息。这个结构体的缺点是没有用特定的变量来区分地址和端口。

    struct sockaddr_in 这个结构体是在<<netinet/in.h>>头文件中定义的。结构体的定义如下:

struct sockaddr_in
{
    sa_family_t     sin_family;   //地址族(Address Family),也就是地址类型
    uint16_t        sin_port;     //16位的端口号
    struct in_addr  sin_addr;     //32位IP地址
    char            sin_zero[8];  //不使用,一般用0填充
};

 其中

struct in_addr
{
    in_addr_t  s_addr;  //32位的IP地址
};

 

       sockaddr_in结构体与sockaddr 结构体的内容是一致的,而且可以相互转换。sockaddr_in结构体中将端口号和地址做了区分,可以更方便用户进行变量的读写。sockaddr则常用于bind、connect、recvfrom、sendto等函数的参数,指明地址信息,是一种通用的套接字地址。所以在程序中通常会采用sockaddr_in进行读写操作,然后转换为sockaddr进行绑定、连接等操作。比如下面的代码。在这段代码中server_addr为sockaddr_in类型的结构体,对这个变量进行相应赋值后,调用bind()函数将server_addr与socket进行绑定,在bind()函数的形参中,将server_addr转换成了sockaddr 类型的结构体。

	bzero(&server_addr,sizeof(struct sockaddr_in));
	server_addr.sin_family = AF_INET;
	server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	server_addr.sin_port = htons(portnumber);

	if(bind(sockfd,(struct sockaddr *)(&server_addr),sizeof(struct sockaddr))==-1)
	{
		fprintf(stderr,"Bind error: %s\n\a",strerror(errno));
		exit(1);	
	}

二、inet_ntoa()和inet_addr()

      inet_ntoa()和inet_addr()这两个函数用来进行IP地址的转换。

其中 inet_ntoa()的完整声明为char *inet_ntoa (struct in_addr);

函数的形参为struct in_addr,它实际上是一个32位的IP地址。这个函数的作用是将32位的IP地址转换为字符串形式的IP地址。如下所示代码

	struct in_addr  adr;
	adr.s_addr=0x0200A8C0;
	printf("IP is: %s\n",inet_ntoa(adr));

执行的结果为

IP is: 192.168.0.2

adr.s_addr=0x0200A8C0;这一句给IP地址复制,它有4个字节组成,这4个字节拆分开转换为10进制为:2、0、168、192,所以转换为字符串为上述的字符串,之所以顺序是反的是因为网络传输过程是大端模式。

       inet_addr()函数的完整声明为in_addr_t inet_addr(const char* cp);

函数发输入为IP地址的字符形式,输出为32位的IP地址,如下所示代码

	in_addr_t adr_x;
	adr_x = inet_addr("192.168.0.100");
	printf("IP address is: 0x%4x\n",adr_x);

执行的结果为

IP address is: 0x6400a8c0

执行结果是将字符串形式的IP地址192.168.0.100,转换成了32位的IP地址。

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
sockaddr_in 是一个用于表示 IPv4 地址的结构体,定义在 `<netinet/in.h>` 头文件中。它的定义如下: ```c struct sockaddr_in { short int sin_family; // 地址族,通常为 AF_INET unsigned short int sin_port; // 端口号 struct in_addr sin_addr; // IPv4 地址 unsigned char sin_zero[8]; // 填充字段,通常为0 }; ``` sockaddr_in 结构体的各个成员参数的含义如下: - `sin_family`:地址族,它指定了地址类型。常用的取值是 `AF_INET`,表示 IPv4 地址族。 - `sin_port`:端口号,用于标识进程间通信的端口。以网络字节序存储,需要使用 `htons()` 函数进行转换。 - `sin_addr`:IPv4 地址,用于存储 IP 地址。它是一个结构体类型(struct in_addr),包含一个无符号 32 位整数(网络字节序),表示 IPv4 地址。 - `sin_zero`:填充字段,通常为0。用于保持与 sockaddr 结构体的大小相同。 示例用法: ```c #include <stdio.h> #include <netinet/in.h> int main() { struct sockaddr_in addr; addr.sin_family = AF_INET; addr.sin_port = htons(8080); addr.sin_addr.s_addr = inet_addr("127.0.0.1"); printf("Address family: %d\n", addr.sin_family); printf("Port: %d\n", ntohs(addr.sin_port)); printf("IP Address: %s\n", inet_ntoa(addr.sin_addr)); return 0; } ``` 上述示例中,我们创建了一个 sockaddr_in 结构体对象 addr,并设置了其各个成员的值。然后,通过相应的函数(如 `htons()` 和 `inet_addr()`)进行格式转换和地址字符串的转换。最后,打印出了各个成员的值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值