600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > TCP关闭连接close socket发送RST导致client读取结果失败

TCP关闭连接close socket发送RST导致client读取结果失败

时间:2021-07-16 03:36:48

相关推荐

TCP关闭连接close socket发送RST导致client读取结果失败

和同事的联调时碰到一个诡异的问题,server端的业务逻辑层面没有任何异常,但返回结果给client端时,并没有发送完所有的数据,就直接发送了RST给client,导致client读取结果失败。注: client与server直接是短连接,server在write所有的数据后会直接close。

通过tcpdump截包对比之前旧版本正常的client端通信,发送server与旧版本的client通信时,三次握手 => client发送数据 => server发送响应数据 => 四次挥手。但与新版本client通信时,则直接是 三次握手 => client发送数据 => server发送响应数据(未完成) => server发送RST。

借助强大的Google大神,以及万能Stackoverflow。原因如下:当close断开连接时,如果缓冲区中又未被读取的数据,则tcp不会发送正常的FIN包,而发送RST给对端。

简单测试一下,代码如下,client和server的主要代码如下:

/*

*client

*/

voidsend_plain_buf(intfd,size_tbuf_size)

{

charbuf[buf_size];

memset(buf,0,buf_size);

intret=write(fd,buf,buf_size);

if(ret<0){

fprintf(stderr,"sendfailed,err[%m]\n");

return;

}

ret=read(fd,buf,1);

if(ret==0){

fprintf(stderr,"clientgetFIN\n");

}else{

fprintf(stderr,"readret[%d],err[%m]",ret);

}

return;

}

/*

*server

*/

voidrecv_plain_buf(intfd,size_tbuf_size)

{

charbuf[buf_size];

memset(buf,0,buf_size);

intret=read(fd,buf,buf_size);

if(ret<0){

fprintf(stderr,"serverrecvfailed,err[%m]\n");

return;

}

return;

}

测试一:client发送1个byte,server读取1个byte,tcpdump截包

21:35:43.829700IPtc-im-nrd306..22579>tc-im-nrd301..8654:S3630522968:3630522968(0)win5840<mss1460,sackOK,timestamp18273110720,nop,wscale7>

21:35:43.829706IPtc-im-nrd301..8654>tc-im-nrd306..22579:S2472593503:2472593503(0)ack3630522969win5792<mss1460,sackOK,timestamp24296503781827311072,nop,wscale7>

21:35:43.829846IPtc-im-nrd306..22579>tc-im-nrd301..8654:.ack1win46<nop,nop,timestamp18273110732429650378>

21:35:43.829873IPtc-im-nrd306..22579>tc-im-nrd301..8654:P1:2(1)ack1win46<nop,nop,timestamp18273110732429650378>

21:35:43.829876IPtc-im-nrd301..8654>tc-im-nrd306..22579:.ack2win46<nop,nop,timestamp24296503781827311073>

21:35:43.829888IPtc-im-nrd301..8654>tc-im-nrd306..22579:F1:1(0)ack2win46<nop,nop,timestamp24296503781827311073>

21:35:43.830035IPtc-im-nrd306..22579>tc-im-nrd301..8654:.ack2win46<nop,nop,timestamp18273110732429650378>

21:35:43.830080IPtc-im-nrd306..22579>tc-im-nrd301..8654:F2:2(0)ack2win46<nop,nop,timestamp18273110732429650378>

21:35:43.830083IPtc-im-nrd301..8654>tc-im-nrd306..22579:.ack3win46<nop,nop,timestamp24296503781827311073>

测试二:client发送2个byte,server读取1个byte,tcpdump截包

21:36:31.137496IPtc-im-nrd306..22580>tc-im-nrd301..8654:S3686863514:3686863514(0)win5840<mss1460,sackOK,timestamp18273583880,nop,wscale7>

21:36:31.137501IPtc-im-nrd301..8654>tc-im-nrd306..22580:S2526723815:2526723815(0)ack3686863515win5792<mss1460,sackOK,timestamp24296976931827358388,nop,wscale7>

21:36:31.137666IPtc-im-nrd306..22580>tc-im-nrd301..8654:.ack1win46<nop,nop,timestamp18273583882429697693>

21:36:31.137671IPtc-im-nrd306..22580>tc-im-nrd301..8654:P1:3(2)ack1win46<nop,nop,timestamp18273583882429697693>

21:36:31.137676IPtc-im-nrd301..8654>tc-im-nrd306..22580:.ack3win46<nop,nop,timestamp24296976931827358388>

21:36:31.137705IPtc-im-nrd301..8654>tc-im-nrd306..22580:R1:1(0)ack3win46<nop,nop,timestamp24296976931827358388>

在net/ipv4/tcp.c:1900行附近的代码如下:

/*AsoutlinedinRFC2525,section2.17,wesendaRSTherebecause

*datawaslost.Towitnesstheawfuleffectsoftheoldbehaviorof

*alwaysdoingaFIN,runanolder2.1.xkernelor2.0.x,startabulk

*GETinanFTPclient,suspendtheprocess,waitfortheclientto

*advertiseazerowindow,thenkill-9theFTPclient,wheee...

*Note:timeoutisalwayszeroinsuchacase.

*/

if(data_was_unread){

/*Unreaddatawastossed,zaptheconnection.*/

NET_INC_STATS_USER(sock_net(sk),LINUX_MIB_TCPABORTONCLOSE);

tcp_set_state(sk,TCP_CLOSE);

tcp_send_active_reset(sk,sk->sk_allocation);

..

标签:TCP

顶一下

(49385)

100.00%

踩一下

(16)

0.00%

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。