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地址。

发布了12 篇原创文章 · 获赞 3 · 访问量 9859

猜你喜欢

转载自blog.csdn.net/bhniunan/article/details/104005751
今日推荐