gpt4 book ai didi

c - 为什么 getsockopt() 没有返回 TCP_MAXSEG 的预期值?

转载 作者:可可西里 更新时间:2023-11-01 02:34:43 31 4
gpt4 key购买 nike

我正在尝试在 GNU/Linux 系统上以编程方式配置我的 TCP 连接的 MSS,特别是 Ubuntu 12.04,内核 3.2.0-68-通用

根据 man 7 tcp

TCP_MAXSEG The maximum segment size for outgoing TCP packets. If this option is set before connection establishment, it also changes the MSS value announced to the other end in the initial packet.Values greater than the (eventual) interface MTU have no effect. TCP will also impose its minimum and maximum bounds over the value provided.

这让我觉得我可以在 连接 TCP 套接字之前配置值。我编写了一小段代码来创建套接字,并使用 setsockopt() 来配置 MSS。在我的测试中,我将 mss 设置为 1000B。

代码调用 setsockopt(),然后调用 getsockopt() 来仔细检查值是否已正确配置。两个系统调用都返回 0(无错误)。之后我连接到远程主机以通过 tcpdump 验证使用的 mss 是否正确。这是我看到的:

  • 从 getsockopt() 返回的 MSS 值总是 536 字节
  • tcpdump 显示 syn 数据包中配置的 MSS

修改我的代码以在连接套接字后配置 MSS。

  • getsockopt() 返回的 MSS 值为 1448 Bye

是否有正确的方法来解释这种行为?

一些注意事项:

  • 根据维基百科 536 B = MaxIPDatagramSize - IPHeaderSize - TcpHeaderSize这是为了避免 IP 数据包碎片化。
  • 创建套接字并连接它(无 setsockopt() 调用),显示 getsockopt() 返回的 mss 为 536 B,但 tcpdump 在 SYN 数据包中显示已公布的 mss 为 1460 B,1500 是有意义的 - IpHeader - TCPHeader

如果你有兴趣,下面是我的代码:

int setSocketMss( int i_sd, int i_mss )
{
int res = 0;
int mss = i_mss;
socklen_t len = sizeof( mss );

res = ::setsockopt( i_sd, IPPROTO_TCP, TCP_MAXSEG, &mss, len );
if ( res < 0 )
{
qDebug() << "error: cannot configure mss for socket" << i_sd;
return -1;
}
res = ::getsockopt( i_sd, IPPROTO_TCP, TCP_MAXSEG, &mss, &len );
if ( mss != i_mss )
{
qDebug() << "MSS set to" << i_mss << "but read value is" << mss;
}
else
{
qDebug() << "MSS for socket" << i_sd << " has been set to" << mss;
}
return mss;
}

void configureAddrStruct( const QString & i_ipAddress,
quint16 i_port,
struct sockaddr_in & o_sockaddr )
{
o_sockaddr.sin_addr.s_addr = htonl( QHostAddress(i_ipAddress).toIPv4Address() );
o_sockaddr.sin_port = htons( i_port );
o_sockaddr.sin_family = PF_INET;
memset( o_sockaddr.sin_zero, 0, sizeof(o_sockaddr.sin_zero) );
}

int main(int argc, char *argv[])
{
int sd = ::socket( PF_INET, SOCK_STREAM, getprotobyname("tcp")->p_proto );
if ( -1 == sd )
{
qDebug() << "erro creating socket";
exit (1);
}
else
{
qDebug() << "created socket:" << sd;
}

setSocketMss( sd, 1000 );

struct sockaddr_in localAddress;
struct sockaddr_in remoteAddress;

configureAddrStruct( "192.168.23.7", 0, localAddress );
configureAddrStruct( "192.168.23.176", 9999, remoteAddress );

int res = ::bind( sd,
reinterpret_cast<const sockaddr *>( &localAddress ),
sizeof(localAddress) );
if ( -1 == res )
{
qDebug() << "error binding socket to local address";
exit(2);
}

//setSocketMss( sd, 1000 );

res = ::connect( sd,
reinterpret_cast<const sockaddr*>( &remoteAddress ),
sizeof(remoteAddress) );
if ( -1 == res )
{
qDebug() << "error connecting to remote host";
::perror( "connect()" );
exit(2);
}

//setSocketMss( sd, 1000 );

return 0;
}

最佳答案

你做错了。您应该在接收方发送套接字接收缓冲区大小。

关于c - 为什么 getsockopt() 没有返回 TCP_MAXSEG 的预期值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25996741/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com