本节我们将为大家介绍套接字的主要API调用的功能和接口描述。
其中,pf为协议族(protocol family)。套接字并不局限于使用TCP/IP,而是可以支持各种协议族。当前的协议族包括TCP/IP互联网(PF_INET)、Xerox公司的PUP互联网(PF_PUP)、Apple公司的AppleTalk网络(PF_APPLETALK)和UNIX文件系统(PF_UNIX)。
type为制定所需的通信类型。包括可靠数据流交付服务(SOCK_STREAM)和无连接数据报交付服务(SOCK_DGRAM)和允许有特权的用户访问网络底层协议和网络接口的原始类型(SOCK_RAW)。
操作系统创建子进程时,子进程将继承父进程打开的套接字。父子进程拥有对该套接字同样的访问权,并且能共享访问套接字。系统对每个套接字的引用进行计数,每增加一个进程访问套接字,则计数加1。当进程完成对套接字的使用时,对套接字的使用调用close进行关闭。close调用将减少套接字的引用计数,并在计数值为0时删除套接字。
以上系统调用的参数中,socket为绑定的套接字描述符。Localaddr为绑定的本地地址的结构,如下图所示。参数addrlen是指定地址长度的整数,以八位组为单位。
一个套接字创建时,并未与任何一个本地或目的地址关联。因此,需要有一种机制将套接字与某个网络地址进行绑定,以便进行传输。套接字在绑定网络地址时,不同协议可能具有不同含义。对TCP/IP协议,绑定的内容包括IP地址和端口号,如下图所示。
初始创建的套接字处于一种未连接的状态,即套接字未与任何外地目的地址关联。系统调用connect将套接字关联到一个永久的目的地址,从而让套接字进入已连接状态。应用程序在进行可靠数据流传输时,必须调用connect建立一个连接。
系统调用参数socket为绑定的套接字描述符。destaddr为目的地址的结构。参数addrlen是指定地址长度的整数,以八位组为单位。
在套接字建立之后,应用程序就可以通过系统调用使用套接字传输数据。有五个系统调用用于传输数据,它们分别是:send、sendto、sendmsg、write和writev。其中send、write和writev只用于已经建立连接的套接字,它们在调用时,不需要,也不允许指定目的地址。
与五个传输数据的系统调用相对应,套接字API也为接收数据提供了五个系统调用。他们分别是:recv、recvfrom、recvmsg、read和readv。
1、进程可以调用getpeername来获得套接字连接的目的方的地址,调用格式如下:
getpeername(socket,destaddr,addrlen)
2、进程也可以通过getsockname获得套接字连接的本地地址,调用格式如下:
getsockname(socket,localaddr,addrlen)
应用程序可以控制套接字的机制。比如设置超时参数,控制缓冲区空间的分配,控制是否允许发送广播,或者控制带外数据的处理等。应用程序可以通过setsockopt设置相应的选项,也可以通过getsockopt获取当前的设置情况。
设置调用的格式如下:
setsockopt(socket,level,optionid,optionval,length)
获取调用的格式如下:
getsockopt(socket,level,optionid,optionval,length)
服务器进程在处理一个请求的时候需要消耗一些时间,在此期间可能系统又有新的请求到来。为了避免协议拒绝或丢弃传入的请求,服务器必须告诉底层协议软件,它希望让来不及处理的请求排队等待。
系统调用listen提供了服务器在一个套接字上等待接收一个请求传入的机制,同时也允许应用程序通过listen调用通知协议软件允许多少请求排队。系统调用的格式为:
listen(socket,qlength)
如果系统请求的队列已满,额外的请求将被丢弃。该系统调用仅用于可靠数据流交付服务的套接字。
服务器进程使用系统调用socket、bind和listen创建一个套接字,将它绑定到熟知端口,并指定连接请求的排队长度。但是套接字并没有连接到外部目的地址,而是处于一种等待状态,准备接收来自任意客户的连接请求。它使用系统调用accept进入阻塞,直到到达一个连接请求。该调用的格式如下:
newsock=accept(socket,addr,addrlen)
其中socket为等待连接的套接字描述符;参数addr是存放地址信息的结构指针;参数addrlen是一个整数的指针,返回地址的长度。
当一个请求到达时,系统将请求方的地址信息填入addr,并通过addrlen表示其长度。之后,系统创建一个新的套接字,该套接字的目的地址连接到请求方,并返回新的套接字的描述符给newsock。原来的套接字仍然保持等待状态,以便继续接收其他的请求。
以上介绍了套接字的一些主要系统调用,还有一些系统调用在教材中有相应的描述。有兴趣的同学可以详细阅读参考教材中的内容。