linux编程网络字节htons以及地址结构sockaddr理解
2016-03-02 21:51
561 查看
最近学习linux编程相关的东西,对sockaddr以及htons等函数有些理解,搜集了一些资料,整理如下:
创建ipv4的地址结构变量并初始化的常见代码如下:
该代码几乎成为所有网络代码的基础,里面主要涉及字节序和sockaddr结构体相关的两个知识点。
其中字节序:
大端序:又称网络序
小端序:PC上主流的字节序
不同PC(或者说CPU)所采用的字节序是不一样的,这样两台PC通信的过程中,会出现字节序不符而导致通信失败,因此API提供相关函数去处理字节序相关的问题,最简单的方法以及本代码所表现出来的,就是统一将机器字节序转化为网络序即大端序,这样通信就可以独立于机器限制了。
初始化struct sockaddr结构体时,用到了两个函数inet_pton,htons,这两个函数均是处理输入并转化为网络序,inet_pton将ip字符串转化为网络序,是inet_aton的改进(string to network的简写),inet_pton能同时处理IPV4,IPV6两种。htons函数(host to network short)将字符串转化为short类型的网络字节序。两个函数的作用这里已经很清楚了,用于字节序的转化。
关于sockaddr结构体,在大部分的API函数中需要的是sockaddr结构体,而我们定义的地址结构体一般为sockaddr_in或者sockaddr_in6来代表IPV4/IPV6地址。其定义如下:
sockaddr_in和sockaddr其地址开始的部分是相同的,即可以相互转化。为何要转化,因为IP4,IP6两种地址并不相同,为了使API能共通用化,所以使用sockaddr能同时接受两种地址的输入。
关于sockaddr参考文章可见:https://beej.us/guide/bgnet/output/html/multipage/sockaddr_inman.html (2016/3/2)
创建ipv4的地址结构变量并初始化的常见代码如下:
int port = 12345;//端口号 const char* ip = "192.168.1.120";//IP struct sockaddr_in address; bzero(&address,sizeof(address)); address.sin_family = AF_INET; inet_pton(AF_INET,ip,&address.sin_addr); address.sin_port = htons(ip); int sock = socket(AF_INET,SOCK_STREAM,0); int ret = bind(sock,(struct sockaddr*)&address,sizeof(address));//地址绑定 或 sock命名
该代码几乎成为所有网络代码的基础,里面主要涉及字节序和sockaddr结构体相关的两个知识点。
其中字节序:
大端序:又称网络序
小端序:PC上主流的字节序
不同PC(或者说CPU)所采用的字节序是不一样的,这样两台PC通信的过程中,会出现字节序不符而导致通信失败,因此API提供相关函数去处理字节序相关的问题,最简单的方法以及本代码所表现出来的,就是统一将机器字节序转化为网络序即大端序,这样通信就可以独立于机器限制了。
初始化struct sockaddr结构体时,用到了两个函数inet_pton,htons,这两个函数均是处理输入并转化为网络序,inet_pton将ip字符串转化为网络序,是inet_aton的改进(string to network的简写),inet_pton能同时处理IPV4,IPV6两种。htons函数(host to network short)将字符串转化为short类型的网络字节序。两个函数的作用这里已经很清楚了,用于字节序的转化。
关于sockaddr结构体,在大部分的API函数中需要的是sockaddr结构体,而我们定义的地址结构体一般为sockaddr_in或者sockaddr_in6来代表IPV4/IPV6地址。其定义如下:
#include <netinet/in.h> // All pointers to socket address structures are often cast to pointers // to this type before use in various functions and system calls: struct sockaddr { unsigned short sa_family; // address family, AF_xxx char sa_data[14]; // 14 bytes of protocol address }; // IPv4 AF_INET sockets: struct sockaddr_in { short sin_family; // e.g. AF_INET, AF_INET6 unsigned short sin_port; // e.g. htons(3490) struct in_addr sin_addr; // see struct in_addr, below char sin_zero[8]; // zero this if you want to }; struct in_addr { unsigned long s_addr; // load with inet_pton() }; // IPv6 AF_INET6 sockets: struct sockaddr_in6 { u_int16_t sin6_family; // address family, AF_INET6 u_int16_t sin6_port; // port number, Network Byte Order u_int32_t sin6_flowinfo; // IPv6 flow information struct in6_addr sin6_addr; // IPv6 address u_int32_t sin6_scope_id; // Scope ID }; struct in6_addr { unsigned char s6_addr[16]; // load with inet_pton() }; // General socket address holding structure, big enough to hold either // struct sockaddr_in or struct sockaddr_in6 data: struct sockaddr_storage { sa_family_t ss_family; // address family // all this is padding, implementation specific, ignore it: char __ss_pad1[_SS_PAD1SIZE]; int64_t __ss_align; char __ss_pad2[_SS_PAD2SIZE]; };
sockaddr_in和sockaddr其地址开始的部分是相同的,即可以相互转化。为何要转化,因为IP4,IP6两种地址并不相同,为了使API能共通用化,所以使用sockaddr能同时接受两种地址的输入。
关于sockaddr参考文章可见:https://beej.us/guide/bgnet/output/html/multipage/sockaddr_inman.html (2016/3/2)
相关文章推荐
- TCP三次握手及释放连接详解
- delphi 利用HTTP的POST方法做个在线翻译的小工具 good
- TCP打洞和UDP打洞的区别
- ISO七层参考模型, TCP/IP
- Nginx为什么比Apache Httpd高效
- 使用maven打包项目遇到错误: http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException
- Linux中的系统和网络资源监测工具:Monitorix
- TCP/IP 要点备忘
- IOS9以上系统请求http报错
- TCP/IP基础(三)
- java网络编程
- Http请求报文和响应报文
- https对应的nginx配置
- 简单配置搞定 Nginx + Tomcat + HTTPS
- Android 网络通信框架Volley简介(Google IO 2013)
- Nginx配置SSL证书部署HTTPS网站
- 数据包分析——传输层(TCP和UDP)
- curl 不支持 https
- Fiddler的使用
- HttpURLConnection加载数据