Linux网络编程---套接字结构

1,结构体 struct  sockaddr,struct sockaddr_in,struct in_addr:

通用套接字数据结构:

struct sockaddr{
      sa_family_t  sa_family ;    /*地址族:AF_XXX*/
      char         sa_data[14] ;  /*14字节的协议地址*/
}
实际使用的套接字数据结构,二者可以进行类型转换:
struct sockaddr_in {
      short int sin_family; /* 地址族 */
      unsigned short int sin_port; /* 端口号 */
      struct in_addr sin_addr; /* Internet地址 */
      unsigned char sin_zero[8]; /* 与struct sockaddr一样的长度 */
};
IP地址的数据结构:
struct in_addr {
      unsigned long s_addr;
};

2,主机字节序和网络字节序转换函数(一般用在整型时)

#include <arpa/inet.h>

uint32_t htonl (uint32_t hostlong)     //主机字节序到网络字节序的长整数转换

uint16_t htons (uint16_t hostshort)       //主机字节序到网络字节序的短整型转换

uint32_t ntohl (uint32_t netlong)      //网络字节序到主机字节序的长整形转换

uint16_t ntohs(uint16_t netshort)      //网络字节序到主机字节序的短整型转换

3,主机字节序IP 和网络字节序IP的转换
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>

/*converts the Internet host address cp from  the  IPv4  num‐bers-and-dots  
  notation  into  binary  form (in network byte order) and stores it in the 
  structure that inp  points  to.*/
int inet_aton(const char *cp,struct in_addr *inp) ;
in_addr_t inet_addr(const char *cp);          /* cp= "xxx.xxx.xxx.xxx" */

/*converts the Internet host address in, given
  in network byte order, to a string  in  IPv4  dotted-decimal  notation.*/
char *inet_ntoa(struct in_addr in);

有两个更新的函数inet_pton和inet_ntop,这2个函数能够处理ipv4和ipv6,原型如下:

int inet_pton(int af, const char *src, void *dst)

这个函数转换字符串到网络地址,第一个参数af是地址族,转换后存在dst中

inet_pton 是inet_addr的扩展,支持的多地址族有下列:

AF_INET:src为指向字符型的地址,即ASCII的地址的首地址(ddd.ddd.ddd.ddd格式的),函数将该地址转换为in_addr的结构体,并复制在*dst中

AF_INET6:rc为指向IPV6的地址,,函数将该地址转换为in6_addr的结构体,并复制在*dst中

如果函数出错将返回一个负值,并将errno设置为EAFNOSUPPORT,如果参数af指定的地址族和src格式不对,函数将返回0。

函数inet_ntop进行相反的转换原型如下:

const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt)

这个函数转换网络二进制结构到ASCII类型的地址,参数的作用和上面相同,只是多了一个参数。


4,gethostbyname函数

     gethostbyname函数引入的原因是因为有时候我们输入的并不一定是一个地址的IP,可能是一个地址的域名或是主机名,比如:

www.google.com。这个时候就需要由主机名得出其IP, 然后得出网络字节序IP 。

函数的原型为:

#include<netdb.h>
#include<sys/socket.h>
struct hostent *gethostbyname(const char *name) ;

struct hostent{
      char  *h_name;            /* 主机的规范名 */
      char **h_aliases;         /* 主机的别名 */
      int    h_addrtype;        /* 主机的地主类型 */
      int    h_length;          /* 主机的地主长度 */
      char **h_addr_list;       /* 主机的IP地址,但是这是以网络字节存储的,不能直接打印,要经过inet_ntop
                                   转换为主机类型的IP才能打印。*/
}
#define h_addr h_addr_list[0] 
sample:

#include<stdio.h>
#include<sys/socket.h>
#include<netdb.h>
#include<arpa/inet.h>
#include<netinet/in.h>

int main(int argc, char *argv[]){
	char des[100] ;
	struct hostent *hp ;
	struct in_addr my_addr ;
	hp = gethostbyname( argv[1] );
	if(hp == NULL ){
		printf("Error!\n");
	}	
	else{
		inet_ntop(AF_INET,hp->h_addr,des,100);
		printf("%s\n",des);
		inet_aton(des,&my_addr);
		printf("%d\n",my_addr.s_addr);	
	}
	return 0; 
}

gcc test.c -o test

./test www.google.com

74.125.71.105
1766292810

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值