免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1389 | 回复: 0
打印 上一主题 下一主题

UNIX网络编程(十四)-套接口选项(二) [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2003-03-15 21:08 |只看该作者 |倒序浏览
    基本套接口选项

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对面相连接的协议如何操作——当由数据残留在套接口发送缓冲区时的处理


  1. LINGER结构

  2. struct linger {
  3. int l_onoff; // 0=off, nonzero=on
  4. int l_linger; //linger time in seconds
  5. };

复制代码

SO_RCVLOWAT 和SO_SNDLOWAT

每个套接口都有一个接收低潮限度和一个发送低潮限度。它们是函数selectt使用的,

接收低潮限度是让select返回“可读”而在套接口接收缓冲区中必须有的数据总量。

——对于一个TCP或UDP套接口,此值缺省为1。发送低潮限度是让select返回“可写”

而在套接口发送缓冲区中必须有的可用空间。对于TCP套接口,此值常缺省为2048。

对于UDP使用低潮限度, 由于其发送缓冲区中可用空间的字节数是从不变化的,只要

UDP套接口发送缓冲区大小大于套接口的低潮限度,这样的UDP套接口就总是可写的。

UDP没有发送缓冲区,只有发送缓冲区的大小。


--------------------------------------------------------------------------------
    TCP 套接口选项

TCP_KEEPALIVE

指定TCP开始发送保持存活探测分节前以秒为单位的连接空闲时间。缺省值至少必须

为7200秒,即2小时。此选项仅在SO_KEPALIVEE套接口选项打开时才有效。

TCP_MAXSEG

获取或设置TCP连接的最大分节大小(MSS)。返回值是我们的TCP发送给另一端的最大

数据量,它常常就是由另一端用SYN分节通告的MSS,除非我们的TCP选择使用一个比

对方通告的MSS小些的值。如果此值在套接口连接之前取得,则返回值为未从另·—端

收到Mss选项的情况下所用的缺省值。小于此返回值的信可能真正用在连接上,因为譬

如说使用时间戳选项的话,它在每个分节上占用12字节的TCP选项容量。我们的TcP将

发送的每个分节的最大数据量也可在连接存活期内改变,但前提是TCP要支持路径MTU

发现功能。如果到对方的路径改变了,此值可上下调整。


--------------------------------------------------------------------------------
    例程序:

  1. //获得发送缓冲区大小和MSS大小,设置发送缓冲区大小

  2. //获得发送缓冲区大小和MSS大小
  3. #include "unp.h"
  4. #include <netinet/tcp.h>; /* for TCP_MAXSEG */
  5. int main(int argc, char **argv)
  6. { int sockfd, rcvbuf, mss;
  7. socklen_t len;
  8. struct sockaddr_in servaddr;
  9. if (argc != 2) err_quit("usage: rcvbuf <IPaddress>;");
  10. sockfd = Socket(AF_INET, SOCK_STREAM, 0);
  11. len = sizeof(rcvbuf);
  12. Getsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, rcvbuf, len);
  13. len = sizeof(mss);
  14. Getsockopt(sockfd, IPPROTO_TCP, TCP_MAXSEG, &mss, &len);
  15. printf("defaults: SO_RCVBUF = %d, MSS = %d\n", rcvbuf, mss);
  16. bzero(servaddr, sizeof(servaddr));
  17. servaddr.sin_family = AF_INET;
  18. servaddr.sin_port = htons(13); /* daytime server */
  19. Inet_pton(AF_INET, argv[1], servaddr.sin_addr);
  20. Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));
  21. len = sizeof(rcvbuf);
  22. Getsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, &len);
  23. len = sizeof(mss);
  24. Getsockopt(sockfd, IPPROTO_TCP, TCP_MAXSEG, &mss, &len);
  25. printf("after connect: SO_RCVBUF = %d, MSS = %d\n", rcvbuf, mss);
  26. exit(0);
  27. }


  28. //设置发送缓冲区大小
  29. #include "unp.h"
  30. #include <netinet/tcp.h>; /* for TCP_MAXSEG value */
  31. int
  32. main(int argc, char **argv)
  33. {
  34. int sockfd, mss, sendbuff;
  35. socklen_t optlen;
  36. float kk;
  37. sockfd = Socket(AF_INET, SOCK_STREAM, 0);
  38. /* Fetch and print the TCP maximum segment size. */
  39. optlen = sizeof(mss);
  40. sendbuff =2048;
  41. Setsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, sendbuff, sizeof(sendbuff));
  42. optlen = sizeof(sendbuff);
  43. Getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, sendbuff, &optlen);
  44. printf("After send buffer size = %d\n", sendbuff);
  45. exit(0);
  46. }

复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP