- 论坛徽章:
- 0
|
SO_KEEPALIVE
检测对方主机是否崩溃,避免(服务器)永远阻塞于TCP连接的输入。
设置该选项后,如果2小时内在此套接口的任一方向都没有数据交换,TCP就自动给对方
发一个保持存活探测分节(keepalive probe)。这是一个对方必须响应的TCP分节.它会导
致以下三种情况:
对方接收一切正常:以期望的ACK响应。2小时后,TCP将发出另一个探测分节。
对方已崩溃且已重新启动:以RST响应。套接口的待处理错误被置为ECONNRESET,套接
口本身则被关闭。
对方无任何响应:源自berkeley的TCP发送另外8个探测分节,相隔75秒一个,试图得到
一个响应。在发出第一个探测分节11分钟15秒后若仍无响应就放弃。套接口的待处理错
误被置为ETIMEOUT,套接口本身则被关闭。如ICMP错误是“host unreachable(主机不
可达)”,说明对方主机并没有崩溃,但是不可达,这种情况下待处理错误被置为
EHOSTUNREACH。
SO_RCVBUF和SO_SNDBUF
每个套接口都有一个发送缓冲区和一个接收缓冲区。
接收缓冲区被TCP和UDP用来将接收到的数据一直保存到由应用进程来读。
TCP:TCP通告另一端的窗口大小。
TCP套接口接收缓冲区不可能溢出,因为对方不允许发出超过所通告窗口大小的数据。
这就是TCP的流量控制,如果对方无视窗口大小而发出了超过宙口大小的数据,则接
收方TCP将丢弃它。
UDP:当接收到的数据报装不进套接口接收缓冲区时,此数据报就被丢弃。UDP是没有
流量控制的;快的发送者可以很容易地就淹没慢的接收者,导致接收方的UDP丢弃数据报。
SO_LINGER
指定函数CLOSE对面相连接的协议如何操作——当由数据残留在套接口发送缓冲区时的处理
- LINGER结构
- struct linger {
- int l_onoff; // 0=off, nonzero=on
- int l_linger; //linger time in seconds
- };
复制代码
SO_RCVLOWAT 和SO_SNDLOWAT
每个套接口都有一个接收低潮限度和一个发送低潮限度。它们是函数selectt使用的,
接收低潮限度是让select返回“可读”而在套接口接收缓冲区中必须有的数据总量。
——对于一个TCP或UDP套接口,此值缺省为1。发送低潮限度是让select返回“可写”
而在套接口发送缓冲区中必须有的可用空间。对于TCP套接口,此值常缺省为2048。
对于UDP使用低潮限度, 由于其发送缓冲区中可用空间的字节数是从不变化的,只要
UDP套接口发送缓冲区大小大于套接口的低潮限度,这样的UDP套接口就总是可写的。
UDP没有发送缓冲区,只有发送缓冲区的大小。
--------------------------------------------------------------------------------
TCP_KEEPALIVE
指定TCP开始发送保持存活探测分节前以秒为单位的连接空闲时间。缺省值至少必须
为7200秒,即2小时。此选项仅在SO_KEPALIVEE套接口选项打开时才有效。
TCP_MAXSEG
获取或设置TCP连接的最大分节大小(MSS)。返回值是我们的TCP发送给另一端的最大
数据量,它常常就是由另一端用SYN分节通告的MSS,除非我们的TCP选择使用一个比
对方通告的MSS小些的值。如果此值在套接口连接之前取得,则返回值为未从另·—端
收到Mss选项的情况下所用的缺省值。小于此返回值的信可能真正用在连接上,因为譬
如说使用时间戳选项的话,它在每个分节上占用12字节的TCP选项容量。我们的TcP将
发送的每个分节的最大数据量也可在连接存活期内改变,但前提是TCP要支持路径MTU
发现功能。如果到对方的路径改变了,此值可上下调整。
--------------------------------------------------------------------------------
- //获得发送缓冲区大小和MSS大小,设置发送缓冲区大小
- //获得发送缓冲区大小和MSS大小
- #include "unp.h"
- #include <netinet/tcp.h>; /* for TCP_MAXSEG */
- int main(int argc, char **argv)
- { int sockfd, rcvbuf, mss;
- socklen_t len;
- struct sockaddr_in servaddr;
- if (argc != 2) err_quit("usage: rcvbuf <IPaddress>;");
- sockfd = Socket(AF_INET, SOCK_STREAM, 0);
- len = sizeof(rcvbuf);
- Getsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, rcvbuf, len);
- len = sizeof(mss);
- Getsockopt(sockfd, IPPROTO_TCP, TCP_MAXSEG, &mss, &len);
- printf("defaults: SO_RCVBUF = %d, MSS = %d\n", rcvbuf, mss);
- bzero(servaddr, sizeof(servaddr));
- servaddr.sin_family = AF_INET;
- servaddr.sin_port = htons(13); /* daytime server */
- Inet_pton(AF_INET, argv[1], servaddr.sin_addr);
- Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
- len = sizeof(rcvbuf);
- Getsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, &len);
- len = sizeof(mss);
- Getsockopt(sockfd, IPPROTO_TCP, TCP_MAXSEG, &mss, &len);
- printf("after connect: SO_RCVBUF = %d, MSS = %d\n", rcvbuf, mss);
- exit(0);
- }
- //设置发送缓冲区大小
- #include "unp.h"
- #include <netinet/tcp.h>; /* for TCP_MAXSEG value */
- int
- main(int argc, char **argv)
- {
- int sockfd, mss, sendbuff;
- socklen_t optlen;
- float kk;
- sockfd = Socket(AF_INET, SOCK_STREAM, 0);
- /* Fetch and print the TCP maximum segment size. */
- optlen = sizeof(mss);
- sendbuff =2048;
- Setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, sendbuff, sizeof(sendbuff));
- optlen = sizeof(sendbuff);
- Getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, sendbuff, &optlen);
- printf("After send buffer size = %d\n", sendbuff);
- exit(0);
- }
复制代码 |
|