socket地址说明及转换函数
来源:互联网 发布:婚纱胸贴哪种好用 知乎 编辑:程序博客网 时间:2024/06/05 08:49
1. 三种常见结构类型
在套接字编程编程中,有三种常见的结构类型,它们用来存放socket地址信息。这三种结构类型分别为struct in_addr、struct sockaddr、struct sockaddr_in,对这三种结构类型说明如下。
struct in_addr专门用来存储IP地址,对于IPv4来说,IP地址为32位无符号整数。其定义如下:
struct in_addr {
unsigned long s_addr;
};
struct sockaddr结构用来保存套接字地址信息,其定义如下:
struct sockaddr {
unsigned short sa_family; /* 地址族, AF_xxx */
char sa_data[14]; /* 14字节的协议地址*/
};
struct sockaddr结构中sa_family成员说明的是地址族类型,一般为“AF_INET”;而sa_data则包含远程主机的IP地址和端口等信息。
struct sockaddr结构类型使用在socket的相关系统调用函数中,但这个结构sa_data字段可以包含较多信息,不利于方便编程和对其进行赋值,因此建立了struct sockaddr_in结构,该结构与struct sockaddr结构大小相等,能更好处理struct sockaddr结构中的数据。对struct sockaddr_in结构变量进行赋值完成后,在进行socket相关系统调用时,再将struct sockaddr_in结构变量强制转换为struct sockaddr结构类型。
struct sockaddr_in结构定义如下:
struct sockaddr_in { /*“in” 代表“Internet”*/
short int sin_family; /* Internet地址族*/
unsigned short int sin_port; /* 端口号*/
struct in_addr sin_addr; /* Internet地址*/
unsigned char sin_zero[8]; /* 填充0(为了保持和struct sockaddr一样大小)*/
};
在实际应用编程中,对套接字地址结构使用方法和流程如下:
① 首先,定义一个sockaddr_in结构变量,并将它初始化为0,代码如下:
struct sockaddr_in myad;
memset(&myad,0,sizeof(struct sockaddr_in));
② 然后,给这个结构变量赋值,代码如下:
myad.sin_family=AF_INET;
myad.sin_port=htons(8080);
myad.sin_addr.s_addr=htonl(INADDR_ANY);
③ 在进行函数调用时,将这个结构强制转换为struct sockaddr类型,代码如下:
bind(serverFd, (struct sockaddr *)& myad, sizeof(myad))
2. 整型字节序转换函数
为保证“大端”和“小端”字节序的机器之间能相互通信,需在发送多字节整数时,将主机字节序转换成网络字节序,或将网络字节序转换为主机字节序。下图说明了网络字节序与小端字节序、大端字节序的对照关系。字节转换主要是针对整型进行转换,字符型由于是单字节,所以不存在这个问题。整型字节序转换函数函数原型及其说明如下表所示。
所需头文件
#include <netinet/in.h>
函数说明
完成网络字节序与主机字节序的转换
函数原型
uint16_t htons(uint16_t hostshort) /*短整型主机转换为网络字节序*/
uint32_t htonl(uint32_t hostlong) /*长整型主机转换为网络字节序*/
uint16_t ntohs(uint16_t netshort) /*短整型网络转换为主机字节序*/
uint32_t ntohl(uint32_t netlong) /*长整型网络转换为主机字节序*/
函数传入值
hostshort、hostlong:为转换前主机字节序数值
netshort、netlong:为转换前网络字节序数值
函数返回值
① htons、htonl返回转换后网络字节序数值
② ntohs、ntohl返回转换后主机字节序数值
附加说明
h表示主机,n表示网络,s表示短整数,l表示长整数,to表示转换
3. IP地址转换函数
IP地址转换函数是指完成点分十进制IP地址与二进制IP地址之间的相互转换。IP地址转换主要有inet_aton、inet_addr和inet_ntoa这三个函数完成,这三个地址转换函数都只能处理IPv4地址,而不能处理IPv6地址。这三个函数的函数原型及其具体说明如下列表格所示。
inet_addr(将点分十进制IP地址转换为二进制地址)
所需头文件
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
函数说明
将点分十进制IP地址转换为二进制地址
函数原型
in_addr_t inet_addr(const char *cp)
函数传入值
cp:点分十进制IP地址,如“10.10.10.1”
函数返回值
成功:返回二进制形式的IP地址
失败:返回一个常值INADDR_NONE(32位均为1)
inet_aton(将点分十进制IP地址转换为二进制地址)
所需头文件
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
函数说明
将点分十进制IP地址转换为二进制地址
函数原型
int inet_aton(const char *cp, struct in_addr *inp)
函数传入值
cp:点分十进制IP地址,如“10.10.10.1”
函数传出值
inp:转换后二进制地址信息保存在inp中
函数返回值
成功:非0
失败:0
inet_ntoa(将二进制地址转换为点分十进制IP地址)
所需头文件
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
函数说明
将二进制地址转换为点分十进制IP地址
函数原型
char *inet_ntoa(struct in_addr in)
函数传入值
in:二进制IP地址
函数返回值
成功:返回字符串指针,此指针指向了转换后的点分十进制IP地址
失败:NULL
4. 获取主机信息函数
(1)getpeername函数原型
getpeername(获取通信对方信息)
所需头文件
#include <netinet/in.h>
函数说明
获取通信对方信息
函数原型
int getpeername(int s, struct sockaddr *name, socklen_t *namelen)
函数传入值
s:所连接的socket文件描述符
namelen:返回name的长度,可以设置为sizeof(struct sockaddr)
函数传出值
name:指向包含对方IP地址、端口等信息的sockaddr结构地址
函数返回值
成功
0
失败
-1,失败原因存于error中
(2)gethostname函数原型
gethostname(获取主机名称)
所需头文件
#include <netinet/in.h>
函数说明
获取通信对方信息
函数原型
int gethostname(char *name, size_t len)
函数传入值
len:name数组的长度
函数传出值
name:主机的名称
函数返回值
成功
0
失败
-1,失败原因存于error中
(3)gethostname函数举例
gethostname.c源代码如下:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
int main()
{
char hostname[30] ;
int flag =0 ;
memset(hostname, 0x00, sizeof(hostname));
flag = gethostname(hostname, sizeof(hostname));
if( flag <0 )
{
perror("gethostname error") ;
return -1 ;
}
printf( "hostname = %s\n", hostname) ;
return 0 ;
}
编译 gcc gethostname.c -o gethostname。
执行 ./gethostname,执行结果如下:
hostname = ubuntu
(4)通过主机名或域名获取IP地址
gethostbyname(通过主机名或域名获取网络信息)
所需头文件
#include <netinet/in.h>
函数说明
gethostbyname会返回一个hostent结构指针,该结构具体说明如下:
struct hostent {
char *h_name; /*正式的主机名称*/
char **h_aliases; /*该主机的其他别名*/
int h_addrtype; /*地址类型,通常是AF_INET*/
int h_length; /*地址的长度*/
char **h_addr_list; /*该主机的所有地址*/
};
函数原型
struct hostent *gethostbyname(const char *name)
函数传入值
name:域名或主机名
函数传出值
name:主机的名称
函数返回值
成功: 返回hostent指针
失败:NULL,失败原因存于h_error中(注意错误原因不存于error中)
附加说明
该函数首先在/etc/hosts文件中查找是否有匹配的主机名。如果没有,则根据在域名解析配置文件
(5)gethostbyname函数举例
gethostbyname.c源代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <netdb.h>
#include <sys/types.h>
#include <netinet/in.h>
int main(int argc, char *argv[])
{
struct hostent *h;
if (argc != 2) { /* error check the command line */
fprintf(stderr,"usage: getip address\n");
return -1;
}
if ((h=gethostbyname(argv[1])) == NULL) { /* get the host info */
herror("gethostbyname");
return -1;
}
printf("Host name : %s\n", h->h_name);
printf("IP Address : %s\n",inet_ntoa(*((struct in_addr *)h->h_addr)));
return 0;
}
编译 gcc gethostbyname.c -o gethostbyname。
执行./gethostbyname www.sina.com,执行结果如下:
Host name : libra.sina.com.cn
IP Address : 202.108.33.83
摘录自《深入浅出Linux工具与编程》- socket地址说明及转换函数
- socket地址说明及转换函数
- socket地址转换函数归纳
- linux socket 地址转换函数
- socket IP地址转换函数
- Linux socket 地址及常用函数
- DELPHI转换函数的定义及说明
- socket结构和几个IP地址转换函数
- socket结构和几个IP地址转换函数
- socket结构和几个IP地址转换函数
- socket结构和几个IP地址转换函数
- socket概述和字节序、地址转换函数(六)
- socket结构和几个IP地址转换函数
- socket listen函数详解及TCP链接过程简要说明
- socket函数说明[转]
- socket函数说明
- socket函数说明
- Socket函数说明
- xml显示(css,xslt)
- Linux内核编译相关介绍
- Navicat for Oracle安装配置笔记(解决ORA-28547错误)
- Pascal's Triangle
- 逐字显示,并使用callback显示下一行
- socket地址说明及转换函数
- Windows共享内存以及相关函数的使用
- LeetCode --- 11. Container With Most Water
- Leetcode NO.34 Search for a Range
- 2014-03-10 Android搭建开发环境
- char*与LPCTSTR相互转化
- mongodb 的配置项启动 和 关闭
- LeetCode --- 12. Integer to Roman
- mongodb 的配置项启动 和 关闭