您的位置:首页 > 理论基础 > 计算机网络

linux网络编程 getsockopt使用TCP_MAXSEG获取MSS时,MSS值与实际值不符问题。

2019-03-15 00:05 323 查看

 学习UNP的时候,习题中有一个获取MSS值和RCVBUF值的练习

第一步:

创建套接字sockfd,在connect之前调用getsockopt函数获取系统中的MSS值和RCVBUF的值

第二步:

调用connect连接服务器端

第三步:

再次获取MSS值和RCVBUF的值

代码如下:

[code]#include "unp.h"
#include <netinet/tcp.h>
int main(int argc, char **argv)
{
int                                     sockfd, n;
char                            recvline[MAXLINE + 1];
struct sockaddr_in      servaddr;

if (argc != 2)
err_quit("usage: a.out <IPaddress>");

if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
err_sys("socket error");
/*-----------------------------------------------------------------*/
//int rcvbuf=0,mss=0,mss1=0;
//socklen_t len=sizeof(rcvbuf);
//getsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, &len);
//printf("RCVBUF = %d\n",rcvbuf);
/*-----------------------------------------------------------------*/

bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port   = htons(13);        /* daytime server */
if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
err_quit("inet_pton error for %s", argv[1]);
/*-----------------------------------------------------------------/
connect之前获取MSS值
/-----------------------------------------------------------------*/
int rcvbuf,mss;
socklen_t len=sizeof(rcvbuf);
getsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, &len);
printf("RCVBUF = %d\n",rcvbuf);
len=sizeof(mss);
getsockopt(sockfd, IPPROTO_TCP, TCP_MAXSEG, &mss, &len);
printf("MSS = %d \n",mss);
/*-----------------------------------------------------------------*/

if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0)
err_sys("connect error");

/*-----------------------------------------------------------------/
再次获取MSS值
/-----------------------------------------------------------------*/
rcvbuf=0;
len=sizeof(rcvbuf);
getsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, &len);
printf("RCVBUF 1 = %d\n",rcvbuf);
//fflush(NULL);
mss=0;
len=sizeof(mss);
getsockopt(sockfd, IPPROTO_TCP, TCP_MAXSEG, &mss, &len);
printf("MSS 1 = %d \n",mss);
//fflush(NULL);
/*-----------------------------------------------------------------*/

int count = 0;
while ( (n = read(sockfd, recvline, MAXLINE)) > 0) {
count++;
recvline
 = 0;        /* null terminate */
if (fputs(recvline, stdout) == EOF)
err_sys("fputs error");
}
printf("count = %d\n",count);
if (n < 0)
err_sys("read error");

exit(0);
}

 运行结果:

[code][root@localhost test]# 7.2 127.0.0.1
RCVBUF = 87380
MSS = 536
RCVBUF 1 = 174758
MSS 1 = 32768
Thu Mar 14 08:12:56 2019
count = 1

我们可以看到,调用connect之前系统默认的值MSS=536,RCVBUF=87380

连接之后MSS=32768,RCVBUF=174758

MSS和RCVBUF的值都产生了变化,原因是连接以后,客户端的MSS将采用对端给定的MSS大小,UNP原话是这样说的

一旦连接建立,本选项的值就是对端通告的MSS选项值,TCP不能发送超过该值的分节。——P172”

所以按照道理,对端通告的值应该是32768

我们现在利用tcpdump获取对端通告的值

[code][root@localhost day13]# tcpdump -i lo host 127.0.0.1
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on lo, link-type EN10MB (Ethernet), capture size 65535 bytes
08:12:56.694657 IP localhost.40966 > localhost.daytime: Flags [S], seq 2114825606, win 65495, options [mss 65495,sackOK,TS val 97357627 ecr 0,nop,wscale 6], length 0
08:12:56.694699 IP localhost.daytime > localhost.40966: Flags [S.], seq 929223868, ack 2114825607, win 65483, options [mss 65495,sackOK,TS val 97357627 ecr 97357627,nop,wscale 6], length 0
08:12:56.694725 IP localhost.40966 > localhost.daytime: Flags [.], ack 1, win 1024, options [nop,nop,TS val 97357627 ecr 97357627], length 0
08:12:56.695408 IP localhost.daytime > localhost.40966: Flags [P.], seq 1:27, ack 1, win 1024, options [nop,nop,TS val 97357627 ecr 97357627], length 26
08:12:56.695429 IP localhost.daytime > localhost.40966: Flags [F.], seq 27, ack 1, win 1024, options [nop,nop,TS val 97357627 ecr 97357627], length 0
08:12:56.695541 IP localhost.40966 > localhost.daytime: Flags [.], ack 27, win 1024, options [nop,nop,TS val 97357627 ecr 97357627], length 0
08:12:56.695736 IP localhost.40966 > localhost.daytime: Flags [F.], seq 1, ack 28, win 1024, options [nop,nop,TS val 97357627 ecr 97357627], length 0
08:12:56.695763 IP localhost.daytime > localhost.40966: Flags [.], ack 2, win 1024, options [nop,nop,TS val 97357627 ecr 97357627], length 0

然而tcpdump抓取的seq里显示对端通告的MSS=65495(TCP最大正常窗口大小65535,TCP首部40字节)

 

问题:

为什么会产生这种结果?

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: