这两个函数仅用于套接字
#include
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
参数:
返回说明:
成功执行时,返回0;失败返回-1,errno被设为以下的某个值 :
#include
#include
int fcntl(int fd, int cmd);
int fcntl(int fd, int cmd, long arg);
int fcntl(int fd, int cmd, struct flock *lock);
fcntl函数提供了与网络编程相关的如下特性:
level有SOL_SOCKET,IPPROTO_IP,IPPROTO_ICMPV6,IPPROTO_IPV6,IPPROTO_TCP,IPPROTO_SCTP,我们主要关注一下常用的SOL_SOCKET,IPPROTO_IP,IPPROTO_TCP这三个level的选项。
选项名 | 说明 | 数据类型 |
---|---|---|
SO_BROADCAST | 允许发送广播数据 | int |
SO_DEBUG | 允许调试 | int |
SO_DONTROUTE | 不查找路由 | int |
SO_ERROR | 获得套接字错误 | int |
SO_KEEPALIVE | 保持连接 | int |
SO_LINGER | 延迟关闭连接 | struct linger |
SO_OOBINLINE | 带外数据放入正常数据流 | int |
SO_RCVBUF | 接收缓冲区大小 | int |
SO_SNDBUF | 发送缓冲区大小 | int |
SO_RCVLOWAT | 接收缓冲区下限 | int |
SO_SNDLOWAT | 发送缓冲区下限 | int |
SO_RCVTIMEO | 接收超时 | struct timeval |
SO_SNDTIMEO | 发送超时 | struct timeval |
SO_REUSERADDR | 允许重用本地地址和端口 | int |
SO_TYPE | 获得套接字类型 | int |
SO_BSDCOMPAT | 与BSD系统兼容 | int |
给一个TCP套接字设置保持存活选项后,如果2小时内在该套接字的任何一方向上都没有数据交换,TCP就自动给对端发送一个保持存活探测分节。这是一个对端必须相应的TCP分节,它会导致以下3种情况之一。
本选项的功能是检测对端主机是否崩溃或变的不可达(譬如拨号调制解调器连接掉线,电源发生故障等等)。如果对端进程崩溃,它的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前设置。
选项名 | 说明 | 数据类型 |
---|---|---|
IP_HDRINCL | 在数据包中包含IP首部 | int |
IP_OPTINOS | IP首部选项 | int |
IP_RECVDSTADDR | 返回目的IP地址 | int |
IP_RECVIF | 返回接收接口索引 | int |
IP_TOS | 服务类型 | int |
IP_TTL | 生存时间 | int |
选项名 | 说明 | 数据类型 |
---|---|---|
TCP_MAXSEG | TCP最大数据段的大小 | int |
TCP_NODELAY | 不使用Nagle算法 | int |
《unix 网络编程 卷一》