iii. linux系统编程_ 37 socket编程_1 预备知识

iii. linux系统编程_ 37 socket编程_1 预备知识

ID:15387872

大小:39.00 KB

页数:3页

时间:2018-08-03

iii. linux系统编程_ 37 socket编程_1 预备知识_第1页
iii. linux系统编程_ 37 socket编程_1 预备知识_第2页
iii. linux系统编程_ 37 socket编程_1 预备知识_第3页
资源描述:

《iii. linux系统编程_ 37 socket编程_1 预备知识》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库

1、第 37 章 socket编程1. 预备知识1.1. 网络字节序我们已经知道,内存中的多字节数据相对于内存地址有大端和小端之分,磁盘文件中的多字节数据相对于文件中的偏移地址也有大端小端之分。网络数据流同样有大端小端之分,那么如何定义网络数据流的地址呢?发送主机通常将发送缓冲区中的数据按内存地址从低到高的顺序发出,接收主机把从网络上接到的字节依次保存在接收缓冲区中,也是按内存地址从低到高的顺序保存,因此,网络数据流的地址应这样规定:先发出的数据是低地址,后发出的数据是高地址。TCP/IP协议规定,网络数据流应采用大端字节序,即低地址高字节。

2、例如上一节的UDP段格式,地址0-1是16位的源端口号,如果这个端口号是1000(0x3e8),则地址0是0x03,地址1是0xe8,也就是先发0x03,再发0xe8,这16位在发送主机的缓冲区中也应该是低地址存0x03,高地址存0xe8。但是,如果发送主机是小端字节序的,这16位被解释成0xe803,而不是1000。因此,发送主机把1000填到发送缓冲区之前需要做字节序的转换。同样地,接收主机如果是小端字节序的,接到16位的源端口号也要做字节序的转换。如果主机是大端字节序的,发送和接收都不需要做转换。同理,32位的IP地址也要考虑网络字

3、节序和主机字节序的问题。为使网络程序具有可移植性,使同样的C代码在大端和小端计算机上编译后都能正常运行,可以调用以下库函数做网络字节序和主机字节序的转换。#includeuint32_thtonl(uint32_thostlong);uint16_thtons(uint16_thostshort);uint32_tntohl(uint32_tnetlong);uint16_tntohs(uint16_tnetshort);这些函数名很好记,h表示host,n表示network,l表示32位长整数,s表示16位短整

4、数。例如htonl表示将32位的长整数从主机字节序转换为网络字节序,例如将IP地址转换后准备发送。如果主机是小端字节序,这些函数将参数做相应的大小端转换然后返回,如果主机是大端字节序,这些函数不做转换,将参数原封不动地返回。1.2. socket地址的数据类型及相关函数socketAPI是一层抽象的网络编程接口,适用于各种底层网络协议,如IPv4、IPv6,以及后面要讲的UNIXDomainSocket。然而,各种网络协议的地址格式并不相同,如下图所示:图 37.1. sockaddr数据结构IPv4和IPv6的地址格式定义在netine

5、t/in.h中,IPv4地址用sockaddr_in结构体表示,包括16位端口号和32位IP地址,IPv6地址用sockaddr_in6结构体表示,包括16位端口号、128位IP地址和一些控制字段。UNIXDomainSocket的地址格式定义在sys/un.h中,用sockaddr_un结构体表示。各种socket地址结构体的开头都是相同的,前16位表示整个结构体的长度(并不是所有UNIX的实现都有长度字段,如Linux就没有),后16位表示地址类型。IPv4、IPv6和UNIXDomainSocket的地址类型分别定义为常数AF_IN

6、ET、AF_INET6、AF_UNIX。这样,只要取得某种sockaddr结构体的首地址,不需要知道具体是哪种类型的sockaddr结构体,就可以根据地址类型字段确定结构体中的内容。因此,socketAPI可以接受各种类型的sockaddr结构体指针做参数,例如bind、accept、connect等函数,这些函数的参数应该设计成void*类型以便接受各种类型的指针,但是sockAPI的实现早于ANSIC标准化,那时还没有void*类型,因此这些函数的参数都用structsockaddr*类型表示,在传递参数之前要强制类型转换一下,例如:

7、structsockaddr_inservaddr;/*initializeservaddr*/bind(listen_fd,(structsockaddr*)&servaddr,sizeof(servaddr));本节只介绍基于IPv4的socket网络编程,sockaddr_in中的成员structin_addrsin_addr表示32位的IP地址。但是我们通常用点分十进制的字符串表示IP地址,以下函数可以在字符串表示和in_addr表示之间转换。字符串转in_addr的函数:#includeintinet_

8、aton(constchar*strptr,structin_addr*addrptr);in_addr_tinet_addr(constchar*strptr);intinet_pton(i

当前文档最多预览五页,下载文档查看全文

此文档下载收益归作者所有

当前文档最多预览五页,下载文档查看全文
温馨提示:
1. 部分包含数学公式或PPT动画的文件,查看预览时可能会显示错乱或异常,文件下载后无此问题,请放心下载。
2. 本文档由用户上传,版权归属用户,天天文库负责整理代发布。如果您对本文档版权有争议请及时联系客服。
3. 下载前请仔细阅读文档内容,确认文档内容符合您的需求后进行下载,若出现内容与标题不符可向本站投诉处理。
4. 下载文档时可能由于网络波动等原因无法下载或下载错误,付费完成后未能成功下载的用户请联系客服处理。