这两个函数仅用于套接字
#include <sys/socket.h> int getsockopt(int sock, int level, int optname, void *optval, socklen_t *optlen); int setsockopt(int sock, int level, int optname, const void *optval, socklen_t optlen); //if success return 0,else return -1参数:
sock:指向一个的打开的套接字描述符,也就是将要被设置或者获取选项的套接字。level:所在协议,或为通用套接字,或为某个特定协议(例如IPv4,IPv6、TCP或SCTP)。 optname:需要访问的选项名。 optval:对于getsockopt(),把已经获取的选项值存放在*optval中。对于setsockopt(),从*optval中取得选项待设置的新值。 optlen:对于getsockopt(),作为入口参数时,选项值的最大长度。作为出口参数时,选项值的实际长度。对于setsockopt(),现选项的长度。返回说明: 成功执行时,返回0;失败返回-1,errno被设为以下的某个值 :
EBADF:sock不是有效的文件描述词EFAULT:optval指向的内存并非有效的进程空间EINVAL:在调用setsockopt()时,optlen无效ENOPROTOOPT:指定的协议层不能识别选项ENOTSOCK:sock描述的不是套接字fcntl函数提供了与网络编程相关的如下特性:
非阻塞式IO。通过使用F_SETFL命令设置O_NONBLOCK文件状态标志,我们可以把一个套接字设置为非阻塞型。 信号驱动IO。通过使用F_SETFL命令设置O_ASYNC文件状态标志,我们可以把一个套接字设置成一旦其状态发生变化,内核就产生一个SIGIO信号。 F_SETOWN命令允许我们指定用于接收SIGIO和SIGURG信号的套接字属主。level有SOL_SOCKET,IPPROTO_IP,IPPROTO_ICMPV6,IPPROTO_IPV6,IPPROTO_TCP,IPPROTO_SCTP,我们主要关注一下常用的SOL_SOCKET,IPPROTO_IP,IPPROTO_TCP这三个level的选项。
给一个TCP套接字设置保持存活选项后,如果2小时内在该套接字的任何一方向上都没有数据交换,TCP就自动给对端发送一个保持存活探测分节。这是一个对端必须相应的TCP分节,它会导致以下3种情况之一。
对端以期望的ACK响应。应用进程得不到通知(因为一切正常)。在又经过仍无动静的2小时后,TCP将发出另一个探测分节。 对端以RST响应,它告知本端TCP:对端已崩溃且已重新启动。该套接字的待处理错误被置为ECONNRESET,套接字本身则被关闭。对端对保持存活探测分节没有任何响应。 如果根本没有对TCP的探测分节的响应,该套接字的待处理错误就被置为ETIMEOUT,套接字本身则被关闭。然而如果该套接字收到一个ICMP错误作为某个探测分节的响应,那就返回响应的错误,套接字本身也被关闭。本选项的功能是检测对端主机是否崩溃或变的不可达(譬如拨号调制解调器连接掉线,电源发生故障等等)。如果对端进程崩溃,它的TCP将跨连接发送一个FIN,这可以通过调用select很容易的检测到。
本选项一般由服务器使用,不过客户也可以使用。服务器使用本选项时因为他们花大部分时间阻塞在等待穿越TCP连接的输入上,也就是说在等待客户的请求。然而如果客户主机连接掉线,电源掉电或者系统崩溃,服务器进程将永远不会知道,并将继续等待永远不会到达的输入。我们称这种情况为半开连接。保持存活选项将检测出这些半开连接并终止他们。
对于另一端发生的各种事件,tcp连接采用的各种检测方法的汇总如下:
情形对端进程崩溃对端主机崩溃对端主机不可达本端TCP正主动发送数据对端tcp发送一个FIN,这通过使用select判断可读条件立即能检测出来。如果本端发送另外一个字节,对端tcp就以RST响应。如果在本端tcp收到RST之后应用进程仍试图写套接字,我们的套接字实现就给该进程发送一个SIGPIPE信号本端tcp将超时,且套接字的待处理错误被设置为ETIMEDOUT本端tcp将超时,且套接字的待处理错误被设置为EHOSTUNREACH本端TCP正主动接收数据对端TCP将发送一个FIN,我们将把它作为一个(可能过早的)EOF读入我们将停止接收数据我们将停止接收数据连接空闲,保持存活选项已设置对端tcp发送一个FIN,这通过使用select判断可读条件立即能检测出来在毫无动静两个小时后,发送9个保持存活探测分节,然后套接字的待处理错误被设置为ETIMEDOUT在毫无动静两个小时后,发送9个保持存活探测分节,然后套接字的待处理错误被设置为EHOSTUNREACH连接空闲,保持存活选项未设置对端tcp发送一个FIN,这通过使用select判断可读条件立即能检测出来无无本选项指定close函数对面向连接的协议(例如TCP和SCTP,但不是UDP)如何操作。默认操作是close立即返回,但是如果有数据残留在套接字发送缓冲区中,系统将试着把这些数据发送给对端。
SO_LINGER如果选择此选项,close或 shutdown将等到所有套接字里排队的消息成功发送或到达延迟时间后才会返回。否则,调用将立即返回。
SO_RCVBUF和SO_SNDBUF每个套接口都有一个发送缓冲区和一个接收缓冲区,使用这两个套接口选项可以改变缺省缓冲区大小。
// 接收缓冲区 int nRecvBuf=32*1024; //设置为32K setsockopt(s,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int)); //发送缓冲区 int nSendBuf=32*1024;//设置为32K setsockopt(s,SOL_SOCKET,SO_SNDBUF,(const char*)&nSendBuf,sizeof(int));注意:当设置TCP套接口接收缓冲区的大小时,函数调用顺序是很重要的,因为三次握手建立连接时,SYN消息同时也会确定窗口大小。对于客户端,SO_RCVBUF选项必须在connect之前设置;对于服务器,SO_RCVBUF选项必须在listen前设置。
《unix 网络编程 卷一》
