gpt4 book ai didi

c - 为什么内核在发送一定数量的字节后会强制从客户端强制发送TCP RST?

转载 作者:行者123 更新时间:2023-12-03 12:07:14 39 4
gpt4 key购买 nike

我有简单的“echo”客户端-服务器代码,并通过tcpdump监视tcp流,客户端在发送274之后始终发送RST。总是。但是我不知道如何找到问题所在。客户端:

//FILE to read from (stdin), sockfd from connect()
void str_cli(FILE *fp, int sockfd)
{
int maxfd;
fd_set rset;
//BSIZE == 4096
char recvline[BSIZE], sendline[BSIZE];
int streamfd = fileno(fp);

//clear the read set
FD_ZERO(&rset);
while (1)
{
FD_SET(streamfd, &rset);
FD_SET(sockfd, &rset);
maxfd = max(streamfd, sockfd) + 1;

//select blocks until one of the fds are readable
if (select(maxfd, &rset, NULL, NULL, NULL) < 0)
{
die("select");
}

if (FD_ISSET(sockfd, &rset))
{
//socket is readable
if (Readline(sockfd, recvline, BSIZE) == 0)
{
die("str_cli: server terminated prematurely");
}
Fputs(recvline, stdout);
}

if (FD_ISSET(streamfd, &rset))
{
//got input and can read from streamfd
if (fgets(sendline, BSIZE, fp) == NULL)
{
//EOF == all done
perror("fgets in select");
return;
}
Writen(sockfd, sendline, strlen(sendline));
}
}
}
服务器:
//sockfd is socket returned from accept()
void str_echo(int sockfd)
{
ssize_t len;
//BSIZE == 4096
char buf[BSIZE];

again:
while ((len = read(sockfd, buf, BSIZE)) > 0)
{
Writen(sockfd, buf, len);
}
if (len < 0 && errno == EINTR)
{
goto again;
}
else if (len < 0)
{
perror("str_echo::read");
}
}
我将BSIZE设置为256,我认为内核由于缓冲区溢出而杀死了客户端,因此我将其更改为4096。但是问题仍然存在,客户端发送 274字节后,在它发送 RST之后,我不知道为什么。最后的转储
127.0.0.1:9877->服务器
127.0.0.1:46790->客户端
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on any, link-type LINUX_SLL (Linux cooked v1), capture size 262144 bytes
IP 127.0.0.1.46790 > 127.0.0.1.9877: Flags [S], seq 1941257529, win 65495, options [mss 65495,sackOK,TS val 2375820429 ecr 0,nop,wscale 7], length 0
IP 127.0.0.1.9877 > 127.0.0.1.46790: Flags [S.], seq 4099864764, ack 1941257530, win 65483, options [mss 65495,sackOK,TS val 2375820429 ecr 2375820429,nop,wscale 7], length 0
IP 127.0.0.1.46790 > 127.0.0.1.9877: Flags [.], ack 1, win 512, options [nop,nop,TS val 2375820429 ecr 2375820429], length 0
IP 127.0.0.1.46790 > 127.0.0.1.9877: Flags [P.], seq 1:37, ack 1, win 512, options [nop,nop,TS val 2375820430 ecr 2375820429], length 36
IP 127.0.0.1.9877 > 127.0.0.1.46790: Flags [.], ack 37, win 512, options [nop,nop,TS val 2375820430 ecr 2375820430], length 0
IP 127.0.0.1.46790 > 127.0.0.1.9877: Flags [P.], seq 37:81, ack 1, win 512, options [nop,nop,TS val 2375820430 ecr 2375820430], length 44
IP 127.0.0.1.9877 > 127.0.0.1.46790: Flags [.], ack 81, win 512, options [nop,nop,TS val 2375820430 ecr 2375820430], length 0
IP 127.0.0.1.46790 > 127.0.0.1.9877: Flags [P.], seq 81:82, ack 1, win 512, options [nop,nop,TS val 2375820430 ecr 2375820430], length 1
IP 127.0.0.1.9877 > 127.0.0.1.46790: Flags [.], ack 82, win 512, options [nop,nop,TS val 2375820430 ecr 2375820430], length 0
IP 127.0.0.1.46790 > 127.0.0.1.9877: Flags [P.], seq 82:92, ack 1, win 512, options [nop,nop,TS val 2375820430 ecr 2375820430], length 10
IP 127.0.0.1.9877 > 127.0.0.1.46790: Flags [.], ack 92, win 512, options [nop,nop,TS val 2375820430 ecr 2375820430], length 0
IP 127.0.0.1.9877 > 127.0.0.1.46790: Flags [P.], seq 1:82, ack 92, win 512, options [nop,nop,TS val 2375820430 ecr 2375820430], length 81
IP 127.0.0.1.9877 > 127.0.0.1.46790: Flags [.], ack 194, win 512, options [nop,nop,TS val 2375820430 ecr 2375820430], length 0
IP 127.0.0.1.46790 > 127.0.0.1.9877: Flags [P.], seq 194:210, ack 82, win 512, options [nop,nop,TS val 2375820430 ecr 2375820430], length 16
IP 127.0.0.1.46790 > 127.0.0.1.9877: Flags [P.], seq 210:226, ack 82, win 512, options [nop,nop,TS val 2375820430 ecr 2375820430], length 16
IP 127.0.0.1.46790 > 127.0.0.1.9877: Flags [P.], seq 226:236, ack 82, win 512, options [nop,nop,TS val 2375820430 ecr 2375820430], length 10
IP 127.0.0.1.9877 > 127.0.0.1.46790: Flags [.], ack 266, win 512, options [nop,nop,TS val 2375820430 ecr 2375820430], length 0
IP 127.0.0.1.9877 > 127.0.0.1.46790: Flags [P.], seq 82:274, ack 274, win 512, options [nop,nop,TS val 2375820430 ecr 2375820430], length 192
IP 127.0.0.1.46790 > 127.0.0.1.9877: Flags [R.], seq 274, ack 274, win 512, options [nop,nop,TS val 2375820430 ecr 2375820430], length 0
19 packets captured
56 packets received by filter
16 packets dropped by kernel
谁知道,为什么内核会强制终止客户端? (通过发送RST)?
编辑:
如果我使用netcat而不是客户端 nc 127.0.0.1 9877 < somefile,则服务器会正​​确地回显它,因此我怀疑客户端在某个地方有问题。但是内核仍然强制使客户端发送RST,但是为什么呢?

最佳答案

问题是,客户端发送完所有字节后,不等待服务器回复并关闭所有套接字(进程exit(0),但是当进程退出时,内核关闭所有打开的文件描述符)。因此,数据是在一端发送的,但是在另一端可以将其回显之前,套接字已关闭。因此,由于接收套接字的缓冲区不是空的,因此答复为RST。从客户端发送字节后,我做了sleep(1)的虚拟解决方案。之后工作了。

关于c - 为什么内核在发送一定数量的字节后会强制从客户端强制发送TCP RST?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65660366/

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