网络编程——sockaddr 与 sockaddr_in
Posted wuyepeng
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网络编程——sockaddr 与 sockaddr_in相关的知识,希望对你有一定的参考价值。
struct sockaddr 这个结构体是linux的网络编程接口中用来表示IP地址的标准结构体,bind、connect等函数中都需要这个结构体,这个结构体是兼容IPV4和IPV6的。
在实际编程中这个结构体会被一个struct sockaddr_in所填充。
sockaddr
用于存储参与(IP)Windows套接字通信的计算机上的一个internet协议(IP)地址。为了统一地址结构的表示方法 ,统一接口函数,使得不同的地址结构可以被bind()、connect()、recvfrom()、sendto()等函数调用。但一般的编程中并不直接对此数据结构进行操作,而使用另一个与之等价的数据结构sockaddr_in。这是由于Microsoft TCP/IP套接字开发人员的工具箱仅支持internet地址字段,而实际填充字段的每一部分则遵循sockaddr_in数据结构,两者大小都是16字节,所以二者之间可以进行切换。
sockaddr 在bind的man手册中提到
struct sockaddr { sa_family_t sa_family; //所选协议族AF_INET char sa_data[14]; //ip地址及端口号 }
而sockaddr_in
struct sockaddr_in { short int sin_family; /* Address family */ unsigned short int sin_port; /* Port number */ struct in_addr sin_addr; /* Internet address */ unsigned char sin_zero[8]; /* Same size as struct sockaddr */ }; sin_family:指代协议族,在socket编程中只能是AF_INET sin_port:存储端口号(使用网络字节顺序) sin_addr:存储IP地址,使用in_addr这个数据结构 sin_zero:是为了让sockaddr与sockaddr_in两个数据结构保持大小相同而保留的空字节。 而其中in_addr结构的定义如下: typedef struct in_addr { union { struct{ unsigned char s_b1,s_b2, s_b3,s_b4;} S_un_b; struct{ unsigned short s_w1, s_w2;} S_un_w; unsigned long S_addr; } S_un; } IN_ADDR;
虽然是两个结构体可是二者的占用的内存是一致的,因此可以互相转化。
sockaddr常用于bind、connect、recvfrom、sendto等函数的参数,指明地址信息。是一种通用的套接字地址。
而sockaddr_in 一般是储存地址和端口的。用于信息的显示及存储使用
例如:
struct sockaddr_in addr_server; addr_server.sin_family = AF_INET; addr_server.sin_port = htons(RPORT); addr_server.sin_addr.s_addr = inet_addr(RHOST);
然而,在类似于bind accept的函数中
ret = bind(fd_sock, (struct sockaddr *)&addr_server, sizeof(addr_server)); if(ret < 0) { perror("bind"); return -1; }
之前只是这样的记下来了,可是知道一天,想显示所连接的客户端的ip地址的时候,就发现了问题所在
char *inet_ntoa(struct in_addr in);
函数原型是这样的,可是在
struct in_addr { in_addr_t s_addr; };
这个in_addr是sockaddr_in的一个mamber
fd_connection = accept(fd_sock, (struct sockaddr *)&addr_client, &addr_client_len); if(fd_connection < 0) { perror("accept"); return -1; } printf("connected! : %d ", fd_connection); printf("%s%s ", "the client ip is :", inet_ntoa(addr_client.sin_addr));
以上是关于网络编程——sockaddr 与 sockaddr_in的主要内容,如果未能解决你的问题,请参考以下文章
socket 编程--sockaddr与sockaddr_in区别与联系(转)
套接字编程,将 sockaddr_in 转换为 sockaddr。为啥?
socket编程 ------ sockaddr_in 和 sockaddr 的区别
套接字编程 connect() 函数错误——“无法将 'main(int, char**)::sockaddr* 转换为 'const sockaddr”