网络编程API

网络编程API
网络编程API

网络API

目录

网络API (1)

索引: .................................................................................................... 错误!未定义书签。

1.字节序函数 (3)

2.字节操作函数 (3)

3.地址转换函数 (3)

4.readn、writen和readline (4)

5.测试描述符类型 (5)

6.socket函数 (5)

7.connect函数 (5)

8.bind函数 (6)

9.listen函数 (7)

10.accept函数 (7)

11.close函数 (7)

12.getsockname和getpeername (8)

13.select函数 (8)

14.shutdown函数 (10)

15.pselect函数 (11)

16.poll函数 (11)

17.getsockopt和setsockopt (13)

18.套接口选项列表 (13)

SO_BINDTODEVICE (15)

SO_BROADCAST (17)

SO_DEBUG (17)

SO_DONTROUTE (17)

SO_ERROR (17)

SO_KEEPALIVE (18)

SO_LINGER (18)

SO_OOBINLINE (19)

SO_RCVBUF和SO_SNDBUF (19)

SO_RCVLOWAT和SO_SNDLOWAT (19)

SO_RCVTIMEO和SO_SNDTIMEO (19)

SO_REUSEADDR和SO_REUSEPORT (20)

SO_TYPE (20)

SO_USELOOPBACK (20)

SO_BINDTODEVICE (21)

IP_HDRINCL (21)

IP_OPTIONS (22)

IP_RECVDSTADDR (22)

IP_RECVIF (22)

IP_TOS (22)

IP_TTL (22)

ICMP6_FILTER (22)

IPV6_ADDRFORM (23)

IPV6_CHECKSUM (23)

IPV6_DSTOPTS (23)

IPV6_HOPLIMIT (23)

IPV6_HOPOPTS (23)

IPV6_NEXTHOP (23)

IPV6_PKTINFO (23)

IPV6_PKTOPTIONS (23)

IPV6_RTHDR (24)

IPV6_UNICAST_HOPS (24)

TCP_KEEPALIVE (24)

TCP_MAXRT (24)

TCP_MAXSEG (24)

TCP_NODELAY (24)

TCP_STDURG (25)

19.处理套接口的fcntl函数 (25)

20.gethostbyname函数 (25)

DNS小常识: (26)

21.gethostbyname2函数 (27)

22.gethostbyaddr函数 (27)

23.uname函数 (27)

24.gethostname函数 (28)

25.getservbyname函数 (28)

26.getservbyport函数 (29)

27.recv和send (29)

28.readv和writev (30)

29.readmsg和writemsg (30)

30.socketpair函数 (32)

31.套接口ioctl函数 (33)

(1)套接口操作 (34)

(2)文件操作 (34)

(3)接口配置 (34)

(4)接口操作 (35)

(5)ARP高速缓存操作 (35)

(6)路由表操作 (35)

1.字节序函数

#include

uint16_t htons(uint16_t host16bitvalue);

uint32_t htonl(uint32_t host32bitvalue);

返回:网络字节序值

uint16_t ntohs(uint16_t net16bitvalue);

uint32_t ntohl(uint32_t net32bitvalue);

返回:主机字节序值

一个测试本机字节序的程序,可参见见unpv12e:intro/byteorder.c。

2.字节操作函数

#include

void bzero(void *dest, size_t nbytes);

void bcopy(const void *src, void *dest, size_t nbytes);

int bcmp(const void *ptr1, const void *ptr2, size_t nbytes);

返回:0—相等,非0—不相等

#include

void *memset(void *dest, int c, size_t len);

void *memcpy(void *dest, void *src, size_t nbytes);

int memcmp(const void *ptr1, const void *ptr2, size_t nbytes);

返回:0—相同,>0或<0—不相同;进行比较操作时,假定两个不相等的字节均为无符号字符(unsigned char)。

3.地址转换函数

#include

int inet_aton(const char *strptr, struct in_addr *addrptr);

返回:1—串有效,0—串有错。

in_addr_t inet_addr(const char *strptr);

返回:若成功,返回32为二进制的网络字节序地址;若有错,则返回INADDR_NONE。

char *inet_ntoa(struct in_addr inaddr);

返回:指向点分十进制数串的指针。

int inet_pton(int family, const char *strptr, void *addrptr);

返回:1—成功;0—输入不是有效的表达格式,-1—出错。

const char *inet_ntop(int family, const void *addrptr, char *strptr, size_t len);

返回:指向结果的指针—成功,NULL—失败。

说明:

?inet_aton函数的指针若为空,则函数仍然执行输入串的有效性检查,但不存储任何结果。

?inet_addr的缺陷:出错返回值INADDR_NONE等于255.255.255.255(IPv4的有限广播地址),所以该函数不能处理此地址。

尽量使用inet_aton,不使用inet_addr。

?inet_ntoa函数的执行结果放在静态内存中,是不可重入的。

?参数family可以是AF_INET,也可以是AF_INET6,若参数family不被支持,则出错,errno置为EAFNOSUPPORT。

?指针addrptr是结构指针。

?len指定目标的大小,避免缓冲区溢出。如果len太小,则返回一个空指针,errno置为ENOSPC。为有助于规定该大小,有如下定义:

#include

#define INET_ADDRSTRLEN 16 /*fro IPv4 dotted-decimal */

#define INET6_ADDRSTRLEN 46 /*for IPv6 hex string */?inet_ntop函数的参数strptr不能为空指针,成功时,此指针即是函数的返回值。

实现IPv4版本的inet_pton和inet_ntop的程序,参见:unpv12e:

libfree/inet_pton_ipv4.c和libfree/inet_ntop_ipv4.c。

4.readn、writen和readline

函数原型如下:

ssize_t readn(int filedes, void *buff, size_t nbytes);

ssize-t writen(int filedes, void *buff, size_t nbytes);

ssize_t readline(int filedes, void *buff, size_t maxlen);

返回:读写字节数,-1—出错。

实现程序见:unpv12e:lib/readn.c、lib/writen.c、lib/readline1.c和

lib/readline.c。

5.测试描述符类型

#include

int isfdtype( int fd, int fdtype);

返回:1—是指定类型,0—不是指定类型,-1—出错。

要测试是否为套接口描述子,fdtype应设为S_IFSOCK。该函数的一个实现程序,参见unpv12e:lib/isfdtype.c

6.socket函数

#include

int socket(int family, int type, int protocol);

返回:非负描述字—成功,-1—出错。

family指定协议族,有如下取值:

?AF_INET IPv4协议

?AF_INET6 IPv6协议

?AF_LOCAL Unix域协议

?AF_ROUTE 路由套接口

?AF_KEY 密钥套接口

type指定套接口类型:

?SOCK_STREAM 字节流套接口

?SOCK_DGRAM 数据报套接口

?SOCK_RAW 原始套接口

protocol一般设为0,除非用在原始套接口上。

并非所有family和type的组合都是有效的。

AF_LOCAL等于早期的AF_UNIX。

7.connect函数

#include

int connect(int sockfd, const struct sockaddr *servaddr, socklen_t addrlen);

返回:0—成功,-1—出错。

sockfd是socket函数返回的套接口描述字,servaddr和addrlen是指向服务器的套接口地址结构指针和结构大小。

在调用connect之前不必非得调用bind函数。

如果是TCP,则connect激发TCP的三路握手过程,在阻塞情况下,只有在连接建立成功或出错时该函数才返回,

出错情况:

?没有收到SYN分节的响应,在规定时间内经过重发仍无效,则返回ETIMEDOUT;

?如果对SYN分节的响应是RST,表示服务器在指定端口上没有相应的服务,返回ECONNREFUSED;

?如果发出 SYN在中间路由器上引发一个目的地不可达ICMP错误,在规定时间内经过重发仍无效,则返回EHOSTUNREACH或ENETUNREACH错误。

注意:如果connect失败,则套接口将不能再使用,必须关闭,不能对此套接口再调用函数connect。

8.bind函数

#include

int bind(int sockfd, const struct sockaddr *maddr, socklen_t addrlen);返回:0—成功,-1—出错。

进程可以把一个特定的IP地址捆绑到他的套接口上,但此IP地址必须是主机的一个接口。

对于IPv4,通配地址是INADDR_ANY,其值一般为0;使用方法如下:

struct sockaddr_in servaddr;

servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

对于IPv6,方法如下:

struct sockaddr_in6 serv;

serv.sin6_addr = in6addr_any; (系统分配变量in6addr_any并将其初始化为常值IN6ADDR_ANY_INIT。)

如果让内核选择临时端口,注意的是bind并不返回所选的断口值,要得到一个端口,必须使用getsockname函数。

bind失败的常见错误是EADDRINUSE(地址已使用)。

9.listen函数

#include

int listen(int sockfd, int backlog);

返回:0—成功,-1—出错。

listen把未连接的套接口转化为被动套接口,指示内核应接受指向此套接口的连接请求。第二个参数规定了内核为此套接口排队的最大连接数。

参数backlog曾经规定为监听套接口上的未完成连接队列和已完成连接队列总和的最大值,但各个系统的定义方法都不尽相同;历史上常把backlog置为5,但对于繁忙的服务器是不够的;backlog的设置没有一个通用的方法,依情况而定,但不要设为0。

10.accept函数

#include

int accept(int sockfd, struct sockaddr *cliaddr, socklen_t *addrlen);返回:非负描述字—OK,-1—出错。

accept从已完成连接队列头返回下一个连接,若已完成连接队列为空,则进程睡眠(套接口为阻塞方式时)。

参数cliaddr和addrlen返回连接对方的协议地址,其中addrlen是值-结果参数,调用前addrlen所指的整数值要置为cliaddr所指的套接口结构的长度,返回时由内核修改。

accept成功执行后,返回一个连接套接口描述字。

如果对客户的协议地址没有兴趣,可以把cliaddr和addrlen置为空指针。11.close函数

#include

int close(int sockfd);

返回:0—OK,-1—出错。

TCP套接口的close缺省功能是将套接口做上“已关闭”标记,并立即返回到进程。这个套接口描述字不能再为进程使用,但TCP将试着发送已排队待发的任何数据,然后按正常的TCP连接终止序列进行操作。

close把描述字的访问计数减1,当访问计数仍大于0时,close并不会引发TCP 的四分组连接终止序列。若确实要发一个FIN,可以用函数shutdown。

12.getsockname和getpeername

#include

int getsockname(int sockfd, struct sockaddr *localaddr, socklen_t

*addrlen);

int getpeername(int sockfd, struct sockaddr *peeraddr, socklen_t

*addrlen);

返回:0—OK,-1—出错。

getsockname函数返回与套接口关联的本地协议地址。

getpeername函数返回与套接口关联的远程协议地址。

addrlen是值-结果参数。

使用场合:

?在不调用bind的TCP客户,当connect成功返回后,getsockname返回分配给此连接的本地IP地址和本地端口号;

?在以端口号为0调用bind后,使用getsockname返回内核分配的本地端口号;

?getsockname可用来获取某套接口的地址族;

?在捆绑了通配IP地址的TCP服务器上,当连接建立后,可以使用getsockname获得分配给此连接的本地IP地址;

?当一个服务器调用exec启动后,他获得客户身份的唯一途径是调用getpeername函数。

13.select函数

#include

#include

int select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set

*exceptset, const struct timeval *timeout);

返回:准备好描述字的正数目,0—超时,-1—出错。

结构timeval的定义:

struct timeval {

long tv_sec; /* seconds */

long tv_usec; /* microseconds */

};

timeout取值的三种情况:

?永远等下去:仅在有一个描述字准备好I/O时才返回,设置timeout为空指针;

?等待固定时间:在有一个描述字准备好I/O时返回,但不超过由timeout 参数所指定的秒数和微秒数;

?根本不等待:检查描述字后立即返回,将timeout中的秒数和微秒数都设置为0。

在等待过程中,若进程捕获了信号并从信号处理程序返回,等待一般被中断,为了可移植性,必须准备好select返回EINTR错误。

timeout的值在返回时并不会被select修改(const标志)。

readset、writeset、exceptset指定我们要让内核测试读、写和异常条件所需的描述字。

当前支持的异常条件有两个:

1.套接口带外数据的到达;

2.控制状态信息的存在,可从一个已置为分组方式的伪终端主端读到。

描述字集的使用:

数据类型:fd_set;

void FD_ZERO(fd_set *fdset);

void FD_SET(int fd, fd_set *fdset);

void FD_CLR(int fd, fd_set *fdset);

void FD_ISSET(int fd, fd_set *fdset);

参数maxfdp1指定被测试的描述字个数,它的值是要被测试的最大描述字加1。描述字0,1,2,…,maxfdp1-1都被测试。

readset、writeset、exceptset是值-结果参数,select修改三者所指的描述字集。所以,每次调用select时,我们都要将所有描述字集中关心的位置为1。

套接口准备好读的条件:

?套接口接收缓冲区中的数据字节数大于等于套接口接收缓冲区低潮限度的当前值。对这样的套接口的读操作将不阻塞并返回一个大于0的值(即准备好读入的数据量)。可以用套接口选项SO_RCVLOWAT来设置低潮限度,对于TCP和UDP,缺省值为1;

?连接的读这一半关闭(接收了FIN的TCP连接)。对这样的套接口读操作将不阻塞并且返回0(即文件结束符);

?套接口是一个监听套接口且已完成的连接数为非0;

?有一个套接口错误待处理。对这样的套接口读操作将不阻塞且返回一个错误,errno设置成明确的错误条件。这些待处理错误也可以通过指定套接口选项SO_ERROR调用getsockopt来取得并清除。

套接口准备好写的条件:

?套接口发送缓冲区中的可用字节数大于等于套接口发送缓冲区低潮限度的当前值,且或者(1)套接口已连接,或者(2)套接口不要求连接(如UDP套接口)。可以用套接口选项SO_SNDLOWAT来设置此低潮限度,对于TCP和UDP,缺省值为2048;

?连接的写这一半关闭。对这样的套接口写将产生信号SIGPIPE;

?有一个套接口错误待处理。对这样的套接口写操作将不阻塞且返回一个错误,errno设置成明确的错误条件。这些待处理错误也可以通过指定套接口选项SO_ERROR调用getsockopt来取得并清除。

如果一个套接口存在带外数据或者仍处于带外标记,那它有异常条件待处理。

一个套接口出错时,它被select标记为既可读又可写。

14.shutdown函数

#include

int shutdown(int sockfd, int howto);

返回:0—成功,-1—失败。

函数的行为依赖于参数howto的值:

?SHUT_RD:关闭连接的读这一半,不再接收套接口中的数据且留在套接口缓冲区中的数据都作废。进程不能再对套接口任何读函数。调用此函数后,由TCP套接口接收的任何数据都被确认,但数据本身被扔掉。

SHUT_WR:关闭连接的写这一半,在TCP场合下,这称为半关闭。当前留在套接口发送缓冲区中的数据都被发送,后跟正常的TCP连接终止序列。

此半关闭不管套接口描述字的访问计数是否大于0。进程不能再执行对套接口的任何写函数。

SHUT_RDWR:连接的读这一半和写这一半都关闭。这等效于调用shutdown两次:第一次调用时用SHUT_RD,第二次调用时用SHUT_WR。

15.pselect函数

#include

#include

#include

int pselect(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set

*exceptset, const struct timespec *timeout, const sigset_t *sigmask);返回:准备好描述字的个数,0—超时,-1—出错。

pselect是Posix.1g发明的。相对select的变化:

1.pselect使用结构timespec:

struct timespec {

time_t tv_sec; /* seconds */

long tv_nsec; /* nanoseconds */

};

新结构中的tv_nsec规定纳秒数。

2.pselect增加了第六个参数:指向信号掩码的指针。允许程序禁止递交某

些信号。

16.poll函数

#include

int poll(struct pollfd *fdarray, unsigned long nfds, int timeout);

返回:准备好描述字的个数,0—超时,-1—出错。

第一个参数是指向一个结构数组的第一个元素的指针,每个数组元素都是一个pollfd结构:

struct pollfd {

int fd; /* descriptor to check */

short events; /* events of interest on fd */

short revents; /* events that occurred on fd */

};

要测试的条件由成员events规定,函数在相应的revents成员中返回描述字的状态(一个描述字有两个变量:一个为调用值,一个为结果)。

第二个参数指定数组中元素的个数。

第三个参数timeout指定函数返回前等待多长时间,单位是毫秒。可能值如下:?INFTIM,永远等待;

?0,立即返回,不阻塞;

?>0,等待指定数目的毫秒数。

常值。

poll识别三个类别的数据:普通(normal)、优先级带(priority band)、高优先级(high priority)。术语来自流的概念。

返回条件:

?所有正规TCP数据和UDP数据都被认为是普通数据;

?TCP的带外数据被认为是优先级带数据;

?当TCP连接的读这一半关闭时(如接收了一个FIN),这也认为是普通数据,且后续的读操作将返回0;

?TCP连接存在错误既可以认为是普通数据,也可以认为是错误(POLLERR)。

无论哪种情况,后续的读操作将返回-1,并将errno置为适当的值,这就处理了诸如接收到RST或超时等条件;

?在监听套接口上新连接的可用性既可认为是普通数据,也可以认为是优先级带数据,大多数实现都将其作为普通数据考虑。

?如果不关心某个特定的描述字,可将其pollfd结构的fd成员置为一个负值,这样就可以忽略成员events,且返回时将成员revents的值置为0。poll没有select存在的最大描述字数目问题。但可移植性select要好于poll。

17.getsockopt和setsockopt

#include

int getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);

int setsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);

返回:0—OK,-1—出错。

sockfd必须是一个打开的套接口描述字;level(级别)指定系统中解释选项的代码:普通套接口代码或特定于协议的代码);optval是一个指向变量的指针;此变量的大小由最后一个参数决定。

对于某些套接口选项,什么时候进行设置或获取是有差别的。下面的套接口选项是由TCP已连接套接口从监听套接口继承来的:

?SO_DEBUG;

?SO_DONTROUTE;

?SO_KEEPALIVE;

?SO_LINGER;

?SO_OOBINLINE;

?SO_RCVBUF;

?SO_SNDBUF。

如果想在三路握手完成时确保这些套接口选项中的某一个是给已连接套接口设置的,我们必须先给监听套接口设置此选项。

18.套接口选项列表

详细说明:

SO_BROADCAST

使能或禁止进程发送广播消息的能力。只有数据报套接口支持广播,并且还必须在支持广播消息的网络上(如以太网、令牌环网等)。

如果目的地址是广播地址但此选项未设,则返回EACCES错误。

SO_DEBUG

仅仅TCP支持。当打开此选项时,内核对TCP在此套接口所发送和接收的所有分组跟踪详细信息。这些信息保存在内核的环形缓冲区内,可由程序trpt进行检查。

SO_DONTROUTE

此选项规定发出的分组将旁路底层协议的正常路由机制。

该选项经常由路由守护进程(routed和gated)用来旁路路由表(路由表不正确的情况下),强制一个分组从某个特定接口发出。

SO_ERROR

当套接口上发生错误时,源自Berkeley的内核中的协议模块将此套接口的名为so_error的变量设为标准的UNIX Exxx值中的一个,它称为此套接口的待处理错误(pending error)。内核可立即以以下两种方式通知进程:

1.如果进程阻塞于次套接口的select调用,则无论是检查可读条件还是可

写条件,select都返回并设置其中一个或所有两个条件。

2.如果进程使用信号驱动I/O模型,则给进程或进程组生成信号SIGIO。

进程然后可以通过获取SO_ERROR套接口选项来得到so_error的值。由getsockopt返回的整数值就是此套接口的待处理错误。so_error随后由内核复位为0。

当进程调用read且没有数据返回时,如果so_error为非0值,则read返回-1且errno设为so_error的值,接着so_error的值被复位为0。如果此套接口上有数据在排队,则read返回那些数据而不是返回错误条件。

如果进程调用write时so_error为非0值,则write返回-1且errno设为

so_error的值,随后so_error也被复位。

SO_KEEPALIVE

打开此选项后,如果2小时内在此套接口上没有任何数据交换,TCP就会自动给对方发一个保持存活探测分节,结果如下:

1.对方以期望的ACK响应,则一切正常,应用程序得不到通知;

2.对方以RST响应,套接口的待处理错误被置为ECONNRESET,套接口本身

则被关闭;

3.对方对探测分节无任何响应,经过重试都没有任何响应,套接口的待处理

错误被置为ETIMEOUT,套接口本身被关闭;若接收到一个ICMP错误作为某个探测分节的响应,则返回相应错误。

此选项一般由服务器使用。服务器使用它是为了检测出半开连接并终止他们。SO_LINGER

此选项指定函数close对面向连接的协议如何操作(如TCP)。缺省close操作是立即返回,如果有数据残留在套接口缓冲区中则系统将试着将这些数据发送给对方。

SO_LINGER选项用来改变此缺省设置。使用如下结构:

struct linger {

int l_onoff; /* 0 = off, nozero = on */

int l_linger; /* linger time */

};

有下列三种情况:

1.l_onoff为0,则该选项关闭,l_linger的值被忽略,等于缺省情况,close

立即返回;

2.l_onoff为非0,l_linger为0,则套接口关闭时TCP夭折连接,TCP将

丢弃保留在套接口发送缓冲区中的任何数据并发送一个RST给对方,而不是通常的四分组终止序列,这避免了TIME_WAIT状态;

3.l_onoff 为非0,l_linger为非0,当套接口关闭时内核将拖延一段时间

(由l_linger决定)。如果套接口缓冲区中仍残留数据,进程将处于睡眠状态,直到(a)所有数据发送完且被对方确认,之后进行正常的终止

序列(描述字访问计数为0)或(b)延迟时间到。此种情况下,应用程

序检查close的返回值是非常重要的,如果在数据发送完并被确认前时间到,close将返回EWOULDBLOCK错误且套接口发送缓冲区中的任何数据都丢失。close的成功返回仅告诉我们发送的数据(和FIN)已由对方TCP

确认,它并不能告诉我们对方应用进程是否已读了数据。如果套接口设为

非阻塞的,它将不等待close完成。

l_linger的单位依赖于实现,4.4BSD假设其单位是时钟滴答(百分之一秒),但Posix.1g规定单位为秒。

让客户知道服务器已经读其数据的一个方法时:调用shutdown(SHUT_WR)而不是调用close,并等待对方close连接的本地(服务器)端。

SO_OOBINLINE

此选项打开时,带外数据将被保留在正常的输入队列中(即在线存放)。当发生这种情况时,接收函数的MSG_OOB标志不能用来读带外数据。

SO_RCVBUF和SO_SNDBUF

每个套接口都有一个发送缓冲区和一个接收缓冲区,使用这两个套接口选项可以改变缺省缓冲区大小。

当设置TCP套接口接收缓冲区的大小时,函数调用顺序是很重要的,因为TCP

的窗口规模选项是在建立连接时用SYN与对方互换得到的。对于客户,SO_RCVBUF 选项必须在connect之前设置;对于服务器,SO_RCVBUF选项必须在listen前设置。

TCP套接口缓冲区的大小至少是连接的MSS的三倍,而必须是连接的MSS的偶数倍。

SO_RCVLOWAT和SO_SNDLOWAT

每个套接口有一个接收低潮限度和一个发送低潮限度,他们由函数select使用。这两个选项可以修改他们。

接收低潮限度是让select返回“可读”而在套接口接收缓冲区中必须有的数据量,对于一个TCP或UDP套接口,此值缺省为1。发送低潮限度是让select返回“可写”而在套接口发送缓冲区中必须有的可用空间,对于TCP套接口,此值常为2048。

SO_RCVTIMEO和SO_SNDTIMEO

使用这两个选项可以给套接口设置一个接收和发送超时。通过设置参数的值为0秒和0微秒来禁止超时。缺省时两个超时都是禁止的。

接收超时影响5个输入函数:read、readv、recv、recvfrom和recvmsg;发送超时影响5个输出函数:write、writev、send、sendto和sendmsg。

SO_REUSEADDR和SO_REUSEPORT

SO_REUSEADDR提供如下四个功能:

1.SO_REUSEADDR允许启动一个监听服务器并捆绑其众所周知端口,即使以

前建立的将此端口用做他们的本地端口的连接仍存在。这通常是重启监听服务器时出现,若不设置此选项,则bind时将出错。

2.SO_REUSEADDR允许在同一端口上启动同一服务器的多个实例,只要每个

实例捆绑一个不同的本地IP地址即可。对于TCP,我们根本不可能启动

捆绑相同IP地址和相同端口号的多个服务器。

3.SO_REUSEADDR允许单个进程捆绑同一端口到多个套接口上,只要每个捆

绑指定不同的本地IP地址即可。这一般不用于TCP服务器。

4.SO_REUSEADDR允许完全重复的捆绑:当一个IP地址和端口绑定到某个

套接口上时,还允许此IP地址和端口捆绑到另一个套接口上。一般来说,这个特性仅在支持多播的系统上才有,而且只对UDP套接口而言(TCP不支持多播)。

SO_REUSEPORT选项有如下语义:

1.此选项允许完全重复捆绑,但仅在想捆绑相同IP地址和端口的套接口都

指定了此套接口选项才性。

2.如果被捆绑的IP地址是一个多播地址,则SO_REUSEADDR和

SO_REUSEPORT等效。

使用这两个套接口选项的建议:

1.在所有TCP服务器中,在调用bind之前设置SO_REUSEADDR套接口选项;

2.当编写一个同一时刻在同一主机上可运行多次的多播应用程序时,设置

SO_REUSEADDR选项,并将本组的多播地址作为本地IP地址捆绑。

SO_TYPE

该选项返回套接口的类型,返回的整数值是一个诸如SOCK_STREAM或SOCK_DGRAM 这样的值。

SO_USELOOPBACK

相关主题
相关文档
最新文档