Linux 系统编程7.pdf
《Linux 系统编程7.pdf》由会员分享,可在线阅读,更多相关《Linux 系统编程7.pdf(17页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、Lecturer:Wang Xiaoniu College of Mathematics and Information Science Northwest Normal University 1第七章 套接字 第七章 套接字 Berkeley 版的 UNIX 引入了一种新的通信工具套接字接口(socket interface),它是管道概念的一个扩展。Linux 支持套接字接口。此外,Microsoft 的 Windows 也通过Windows Sockets 技术规范(简称 WinSock)支持套接字接口。因此,Windows和Linux可通过套接字来实现网络通信,满足许多应用需求。虽然W
2、inSock和 Linux 套接字不尽相同,但都以套接字为基础。网络编程中使用最广泛的模型就是客户机-服务器模型。这个模型中有管理资源的服务器进程,和需要对共享资源进行访问的客户机进程。其特点是:?由客户,而不是服务提供者,发起动作。?服务器被动的等待来自客户机的请求。?服务器要能够处理多个同时发出的客户机请求。另外还有事件通知机制和 P2P 计算等模型。相对复杂。还有一种说法。套接字是 TCP/IP 协议的设计者创建的一个接口,以便应用程序利用这个接口能很方便的进行通信。这不是 OS 在 TCP/IP 和应用程序之间设计的接口。1.套接字属性 套接字的特性由四个属性确定,它们是:域(doma
3、in)、地址(address)、类型(type)和协议(protocol)。1.1 套接字的域套接字的域 域指定套接字通信中使用的网络介质。最常见的套接字域是 AF_INET,它指的是互联网络。还有一个域是 AF_UNIX,它指的是本地文件系统,如果在单机上通过套接字实现进程间通信,就用 AF_UNIX 域。另外还有 AF_ISO(基于 ISO 标准协议的网络)和 AF_XNS(基于施乐网络系统)。1.2 套接字的地址套接字的地址 不同的域有不同的套接字地址。对于 AF_UNIX 来说,套接字的地址就是本地文件系统上一个绝对路径的文件名。对于 AF_INET 来说,套接字的地址就是本地 IP
4、地址以及一个合适的端口号,可以把端口号理解为最终的逻辑信道(两机之间有一条最初的逻辑信道IP,接着有两条中间的逻辑信道TCP 和 UDP,然后有若干最终的逻辑信道端口)。Lecturer:Wang Xiaoniu College of Mathematics and Information Science Northwest Normal University 21.3 套接字的类型套接字的类型 有两种截然不同的套接字类型:流(SOCK_STREAM):提供有序、可靠、双向字节流的连接,其行为可见。由 TCP支持;数据报(SOCK_DGRAM):不建立和维持一个连接,对数据包的长度有限制,可能
5、丢失、乱序或重复到达。由 UDP 支持。1.4 套接字的协议套接字的协议 在大多数的实现中,每一种套接字类型只能使用一种协议。因此,通常忽略协议。2.套接字连接 2.1 创建套接字创建套接字 socket 系统调用创建一个套接字并返回一个文件描述符(所有的东西都抽象成文件),可以通过该文件描述符来访问该套接字。具体参数如前所述。SYNOPSIS#include#include int socket(int domain,int type,int protocol);如果成功,socket 返回一个对应于套接字文件描述符的非负整数,否则,返回-1 并设置errno。下表列出了 socket 实现
6、必须检测的错误和相应的错误码。errno 原因 EAFNOSUPPORT 本实现不支持指定的地址簇 EMFILE 进程不再有文件描述符可用 ENFILE 系统不再有文件描述符可用 EPROTONOSUPPORT 地址簇或本实现不支持协议 EPROTOTYPE 协议不支持套接字类型 下面代码为网络通信建立了一个面向连接的套接字:int sockfd;if(sockfd=socket(AF_INET,SOCK_STREAM,0)=-1)perror(“Failed to create socket”);Lecturer:Wang Xiaoniu College of Mathematics and
7、 Information Science Northwest Normal University 32.2 绑定套接字绑定套接字 必须为套接字绑定一个地址。对于客户机来说,程序员不需要显式地知道套接字地址(因为服务器不需要主动来连接),因此绑定工作由系统隐式完成(IP 地址就是本地主机,端口程序员不需要知道)。但在客户机上仍然要有服务器地址的描述,因为客户机要向这个地址连接。对于服务器来说,则必须显式绑定地址(这样客户机才能知道这个地址)。对于本地文件系统域(AF_UNIX)来说,其地址结构由 sockaddr_un 来描述。#include struct sockaddr_un sa_fam
8、ily_t sun_family;char sun_path;显然,sun_family 应该为 AF_UNIX,而 sun_path则为一个绝对路径的文件名。对于互联网络域(AF_INET)来说,其地址结构由 sockaddr_in 来描述。#include struct sockaddr_in short int sin_family;unsigned sin_port;struct in_addr sin_addr;同样,sin_family 为 AF_INET,sin_port 为指定的端口号,in_addr 结构有一个成员 s_addr,其类型为 in_addr_t,用于装载 IP
9、地址的数字值。所以应将 IP 地址赋值给 sin_addr.s_addr。服务器可以将 sin_addr.s_addr 字段设置为 INADDR_ANY,表示套接字可以接收任何一个主机网络接口上的连接请求。客户机将 sin_addr.s_addr 字段设置为服务器主机的 IP 地址。在不同的系统上,IP 地址(32 位)和端口号(16 位)存在字节序问题。以下函数解决这一问题。#include unsigned long int htonl(unsigned long int hostlong);Lecturer:Wang Xiaoniu College of Mathematics and
10、Information Science Northwest Normal University 4unsigned short int htons(unsigned short int hostshort);unsigned long int ntohl(unsigned long int netlong);unsigned short int ntohs(unsigned short int netshort);另外,在实际应用中还可能需要以下两个函数,inet_addr 负责将一个点分表示的 IP 地址转换成符合网络序的 32 长整型数,inet_ntoa 将 32 位 IP 地址转换为可
11、打印的字符串。#include in_addr_t inet_addr(char*ipaddr);char*inet_ntoa(struct in_addr in);bind 系统调用为一个已定义的套接字绑定一个地址。其中参数 socket 是 socket 函数返回的文件描述符,*address 结构包含一个协议地址簇,因为不同的地址长度不一,因此 bind函数还需一个描述地址长度的参数 address_len。#include int bind(int socket,const struct sockaddr*address,socklen_t address_len);如果成功,bind
12、 返回 0。否则返回-1 并设置 errno。下表列出 bind 的实现必须检测的错误和相应的错误码,这适用于所有的地址簇。errno 原因 EADDRINUSE 指定的地址正在使用中 EADDRNOTAVAIL 本地机上不存在指定的地址 EAFNOSUPPORT 对指定的套接字所使用的地址来说,地址无效 EBADF 参数 socket 不是有效的文件描述符 EINVAL 套接字已经绑定到一个地址,协议不支持绑定到新地址,或者套接字已经被关闭了 ENOTSOCK 参数 socket 没有指向套接字 EOPNOTSUPP 套接字类型不支持对地址的绑定 AF_UNIX 域的地址类型是 struct
13、 sockaddr_un,AF_INET 域的地址类型是 struct sockaddr_in,POSIX 规定应用程序在和套接字函数一同使用时要将 sockaddr_un 和sockaddr_in 强制转换成 struct soakaddr。下面的代码段将端口 8652 与一个已定义的套接字 mysocket 绑定,允许接收任何主机的Lecturer:Wang Xiaoniu College of Mathematics and Information Science Northwest Normal University 5连接请求。struct sockaddr_in serveradd
14、r;int mysocket;serveraddr.sin_family=AF_INET;serveraddr.sin_addr.s_addr=htonl(INADDR_ANY);serveraddr.sin_port=htons(8652);if(bind(mysocket,(struct sockaddr*)&serveraddr,sizeof(serveraddr)=-1)perror(“Failed to bind the socket to port”);2.3 监听套接字监听套接字 绑定套接字后,客户机就可以通过该套接字与服务器进行连接。当客户机向服务器的某个套接字发出连接请求时,
15、客户机和服务器的底层网络子系统交换信息(TCP 的三次握手)以建立连接。可能服务器正忙,不能立即响应客户机的请求(这几乎是服务器的常态),因此服务器就要为针对某个套接字(其实就是 IP、协议、端口的一个地址)的连接请求建立一个缓存队列。同时,服务器需要对该套接字启动监听(可以想象,服务器同时可能会收到很多不同地址(如果有的话)、不同协议(TCP/UDP)、不同端口的请求)。这些工作由系统调用 listen 来完成。#include int listen(int socket,int backlog);如果成功,listen 返回 0,否则返回-1 并设置 errno。下表列出了 listen
16、的实现必须检测的错误及相应的错误码。errno 原因 EDESTADDRREQ 套接字没有绑定到一个本地地址上去,且协议不允许监听未绑定的套接字 EBADF 参数 socket 不是有效的文件描述符 EINVAL 套接字已经绑定到一个地址,协议不支持绑定到新地址,或者套接字已经被关闭了 ENOTSOCK 参数 socket 没有指向套接字 EOPNOTSUPP 套接字类型不支持对地址的绑定 Lecturer:Wang Xiaoniu College of Mathematics and Information Science Northwest Normal University 62.4 响
17、应套接字响应套接字 一旦服务器程序 socket、bind 并 listen 了一个套接字之后,它就可以调用 accept 系统调用来等待客户机建立对该套接字的连接。accept 与客户机的 connect 系统调用对应,它挂起调用者,直到客户机向该套接字请求连接(connect),随后双方通过网络底层进行三次握手,建立连接,最后返回客户端的地址(IP 和端口)。#include int accept(int socket,struct sockaddr*address,size_t*address_len);如果成功,accept 将创建一个新套接字与该客户机进行通信,并返回该新套接字的描述
18、符,在*address 中返回客户机的地址,在*address_len 中返回客户机地址的长度。服务器一开始创建的套接字作为监听套接字继续监听新的客户机的请求。新套接字与监听套接字的类型是一样的。如果不成功,accept 返回-1 并设置 errno。下表列出了 accept 的实现必须检测的错误及相应的错误码。errno 原因 EAGAIN 或 EWOULDBLOCK 套接字文件描述符设置了 O_NOBLOCK,并且没有需要接受的连接 ECONNABORTED 连接以被放弃 EINTR accept 被一个信号中断,这个信号在有效连接到来之前就被捕捉了 EMFILE 在调用进程中,有 OPE
19、N_MAX 个文件描述符打开着 ENFILE 系统中已经打开的文件描述符的数量已经达到最大值 EBADF 参数 socket 不是有效的文件描述符 EINVAL 套接字已经绑定到一个地址,协议不支持绑定到新地址,或者套接字已经被关闭了 ENOTSOCK 参数 socket 没有指向套接字 EOPNOTSUPP 套接字类型不支持对地址的绑定 2.5 请求套接字请求套接字 客户机调用 connect 系统调用在一个未命名套接字和服务器监听套接字之间建立连接。Lecturer:Wang Xiaoniu College of Mathematics and Information Science No
20、rthwest Normal University 7#include int connect(int socket,const struct sockaddr*address,size_t address_len);参数 socket 指定的套接字将连接到参数 address 指定的服务器套接字上。如果成功,connect 返回 0,否则返回-1 并设置 errno。下表列出了 connect 的实现必须检测的错误及相应的错误码。errno 原因 EADDRNOTAVAIL 本机上没有指定的地址 EAFNOSUPPORT 对指定的套接字地址族来说,指定的地址是无效地址 EALREADY 连接
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Linux 系统编程7 系统 编程
限制150内