专栏首页架构说60秒问答:系统调用之send函数

60秒问答:系统调用之send函数

今天上午 回顾了 TCP/IP编程之select函数详解 ,发现还有问题。进行总结

问:系统调用函数send 返回值 可能是0吗?

查看 man send 
On success, these calls return the number of characters sent
这个没说明 是不是0呢?

答:

  • 不可能 【推测】
  • 因为,read 返回 0表示正常结束,

但是通过实践经验 send 表示 发送到本地缓冲区,数据不一定发送过去, 还有第二次概念 因此推断 不会返回0.

问:send场景:

像已经关闭的tcp连接,send 数据 第一次会触发RST。这个RST怎么检测,依靠send吗?第二次 send 返回管道信号,如何检测 依靠send吗?

答:

  • 解决方案1:第一次会触发RST,send无法解决?非阻塞模型下,select或者epoll会返回sockfd可读,应用层对其进行读取时, 收到RST的client端,如果调用read函数,读取,是返回RST错误的
  • 解决方案2:可以 第二次 send 返回管道信号 管道信号是异步的,信号是程序无法try catch的 需要信号处理函数。

但是内核可以控制send 不发送管道信号。

但是liunx 提供一个send参数

MSG_NOSIGNAL (since Linux 2.2)
Requests not to send SIGPIPE on errors on stream oriented sockets when the other end breaks the connection. The EPIPE error is still returned.
ssize_t send(int sockfd, const void *buf, size_t len, int flags)

EPIPE
The local end has been shut down on a connection oriented socket. In this case the process will also receive a SIGPIPE unless MSG_NOSIGNAL is set.
EAGAIN or EWOULDBLOCK

read 三个参数:
ssize_t read(int fd, void *buf, size_t count);
https://linux.die.net/man/2/read
send:四个参数
ssize_t send(int sockfd, const void *buf, size_t len, int flags);

问:接受到RST报文,不需要进行ack,另一端根本不进行确认。收到RST的一方将终止该连接

什么是RST,有什么意义?

答:

什么是RST?

RST 是个flag

https://www.ietf.org/rfc/rfc793.txt TCP Header Format

                                    
    0                   1                   2                   3   
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |          Source Port          |       Destination Port        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                        Sequence Number                        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                    Acknowledgment Number                      |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |  Data |           |U|A|P|R|S|F|                               |
   | Offset| Reserved  |R|C|S|S|Y|I|            Window             |
   |       |           |G|K|H|T|N|N|                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |           Checksum            |         Urgent Pointer        |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                    Options                    |    Padding    |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                             data                              |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   
 Control Bits:  6 bits (from left to right):

    URG:  Urgent Pointer field significant
    ACK:  Acknowledgment field significant
    PSH:  Push Function
    RST:  Reset the connection
    SYN:  Synchronize sequence numbers
    FIN:  No more data from sender

RST表示复位,用来异常的关闭连接,在TCP的设计中它是不可或缺的。就像上面说的一样,发送RST包关闭连接时,不必等缓冲区的包都发出去(不像上面的FIN包),直接就丢弃缓存区的包发送RST包。而接收端收到RST包后,也不必发送ACK包来确认。

TCP处理程序会在自己认为的异常时刻发送RST包。例如,A向B发起连接,但B之上并未监听相应的端口,这时B操作系统上的TCP处理程序会发RST包。

又比如,

AB正常建立连接了,正在通讯时,A向B发送了FIN包要求关连接,B发送ACK后,网断了, A通过若干原因放弃了这个连接(例如进程重启)。网通了后, B又开始发数据包,A收到后表示压力很大,不知道这野连接哪来的, 就发了个RST包强制把连接关了, B收到后会出现connect reset by peer错误。

根据TCP协议的规定,会收到一个RST响应,client再往这个服务器发送数据时, 系统会发出一个SIGPIPE信号给进程,告诉进程这个连接已经断开了,不要再写了。

又或者当一个进程向某个已经收到RST的socket执行写操作是, 内核向该进程发送一个SIGPIPE信号。该信号的缺省学位是终止进程,因此进程必须捕获它以免不情愿的被终止

对发送和和接受方都有意义。

异常关闭一个连接对应用程序来说有两个优点:

(1)丢弃任何待发的已经无意义的 数据,并立即发送RST报文段;

(2)RST的接收方利用关闭方式来 区分另一端执行的是异常关闭还是正常关闭 (通过read操作的返回值,正常的返回读取字节或者堵塞,RST的返回错误)read

Return Value On success, the number of bytes read is returned (zero indicates end of file) On error, -1 is returned, and errno is set appropriately

EAGAIN or EWOULDBLOCK EINTR EBADF fd is not a valid file descriptor or is not open for reading.

https://zhuanlan.zhihu.com/p/149265232

TCP异常终止(reset报文) 场景

直接释放连接:

5,有些应用开发者在设计应用系统时,会利用reset报文快速释放已经完成数据交互的TCP连接,以提高业务交互的效率,如下图所示:

在交互的双方中的某一方长期未收到来自对方的确认报文,则其在超出一定的重传次数或时间后,会主动向对端发送reset报文释放该TCP连接

  • 正常情况下连接关闭
     TCP A                                                TCP B

  1.  ESTABLISHED                                          ESTABLISHED

  2.  (Close)
      FIN-WAIT-1  --> <SEQ=100><ACK=300><CTL=FIN,ACK>  --> CLOSE-WAIT【被动关闭,只要对方发送closed】

  3.  FIN-WAIT-2  <-- <SEQ=300><ACK=101><CTL=ACK>      <-- CLOSE-WAIT

  4.                                                       (Close)
      TIME-WAIT   <-- <SEQ=300><ACK=101><CTL=FIN,ACK>  <-- LAST-ACK[等待ack,CLOSE-WAIT 需要确认的。]

  5.  TIME-WAIT   --> <SEQ=101><ACK=301><CTL=ACK>      --> CLOSED

  6.  (2 MSL)
      CLOSED                                                      

                         Normal Close Sequence

                               Figure 13.

  

      TCP A                                                TCP B

  1.  ESTABLISHED                                          ESTABLISHED

  2.  (Close)                                              (Close)
      FIN-WAIT-1  --> <SEQ=100><ACK=300><CTL=FIN,ACK>  ... FIN-WAIT-1
                  <-- <SEQ=300><ACK=100><CTL=FIN,ACK>  <--
                  ... <SEQ=100><ACK=300><CTL=FIN,ACK>  -->

  3.  CLOSING     --> <SEQ=101><ACK=301><CTL=ACK>      ... CLOSING
                  <-- <SEQ=301><ACK=101><CTL=ACK>      <--
                  ... <SEQ=101><ACK=301><CTL=ACK>      -->

  4.  TIME-WAIT                                            TIME-WAIT
      (2 MSL)                                              (2 MSL)
      CLOSED                                               CLOSED

                      Simultaneous Close Sequence

                               Figure 14.

4,在交互的双方中的某一方长期未收到来自对方的确认报文,则其在超出一定的重传次数或时间后,会主动向对端发送reset报文释放该TCP连接

3,接收端收到TCP报文,但是发现该TCP的报文,并不在其已建立的TCP连接列表内,则其直接向对端发送reset报文

2,客户端和服务器的某一方在交互的过程中发生异常(如程序崩溃等),该方系统将向对端发送TCP reset报文,告之对方释放相关的TCP连接 【服务crash但是 主机和网络正常】

An interesting alternative case occurs when TCP A crashes and TCP B tries to send data on what it thinks is a synchronized connection.

1,客户端尝试与服务器未对外提供服务的端口建立TCP连接,服务器将会直接向客户端发送reset报文。

塔山

  • https://blog.csdn.net/polarbearboy/article/details/6691405
  • http://blog.sina.com.cn/s/blog_6c2e6f1f0100ok4y.html
  • http://bbs.chinaunix.net/thread-838813-1-1.html

本文分享自微信公众号 - 架构说(JiaGouS),作者:王传义

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2021-07-03

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 60秒问答:多态和函数重载的关系?

    运行时的多态:通过类继承和虚函数实现的(根据虚表指针 指向 派生类的函数,还是基类的函数)

    程序员小王
  • [干货实战]为最佳性能调优nginx

    通常来说,一个优化良好的 Nginx Linux 服务器可以达到 500,000 – 600,000 次/秒 的请求处理性能,然而我的 Nginx 服务器可以稳...

    后端技术探索
  • Nginx支持QUIC/HTTP3的实现路径和实践思考(内含ppt)

    https://http3-explained.haxx.se/en/why-quic/why-tcphol

    程序员小王
  • 为最佳性能调优 Nginx

    通常来说,一个优化良好的 Linux 服务器可以达到 500,000 – 600,000 次/秒 的请求处理性能,然而我的 Nginx 服务器可以稳定地达到 9...

    用户1263954
  • OpenResty学习指南(一)

    我的博客: https://www.luozhiyun.com/archives/217

    luozhiyun
  • 服务器开发中网络数据分析与故障排查经验漫谈

    一、 操作系统提供的网络接口 为了能更好的排查网络通信问题,我们需要熟悉操作系统提供的以下网络接口函数,列表如下: 接口函数名称接口函数描述接口函数签名soc...

    范蠡
  • 深入iOS系统底层之函数调用

    可执行程序是为了实现某个功能而由不同机器指令按特定规则进行组合排列的集合。无论高级还是低级程序语言,无论是面向对象还是面向过程的语言最终的代码都会转化为一条条机...

    欧阳大哥2013
  • 速度不够,管道来凑——Redis管道技术

    Redis客户端与服务器之间使用TCP协议进行通信,并且很早就支持管道(pipelining)技术了。在某些高并发的场景下,网络开销成了Redis速度的瓶颈,所...

    用户5546570
  • 服务器开发中网络数据分析与故障排查经验谈

    为了能更好的排查网络通信问题,我们需要熟悉操作系统提供的以下网络接口函数,列表如下:

    范蠡
  • 等保测评:Centos超时退出详解

    等保测评主机测评中需要查询主机的超时退出配置,具体在Centos中的话,主要有两种方式可以实现超时退出的功能。其实这方面的资料很多,但是仍然存在一些地方没有说清...

    FB客服
  • 【修正版】动图图解!代码执行send成功后,数据就发出去了吗?

    编程的时候,如果要跟某个IP建立连接,我们需要调用操作系统提供的 socket API。

    9号同学
  • 如何用 ajax 连接mysql数据库,并且获取从中返回的数据。ajax获取从mysql返回的数据。responseXML分别输出不同数据的方法。

          开讲前,先说下网上,大部分的关于这方面的博文或者其他什么的,就我自己的感觉,第一说得不详细,第二语言不能很好的被初学者了解。 我这篇的标题之所以用了...

    林冠宏-指尖下的幽灵
  • 【Web Function】基于Express架构的云端计算器服务开放与部署

    Web Function,也叫 Web 函数,是云函数的一种函数类型,区别于事件函数对于事件格式的限制,更加专注于优化 Web 服务场景,用户可以直接发送 HT...

    liuzhen007
  • 深入分析网络编程中踩过的坑

    网络编程中经常会遇到一些异常的情况,定位问题需要了解协议栈的实现,以下是工作中遇到的一些常见问题的深入分析和解决思路。 问题1:server端业务进程响应心...

    QQ音乐技术团队
  • 进程间通讯(三).signal

    UNIX/Linux 是多任务的操作系统,通过多个进程分别处理不同事务来实现,如果多个进程要进行协同工作或者争用同一个资源时,互相之间的通讯就很有必要了

    franket
  • TCP socket和web socket的区别

    版权声明:本文为博主汪子熙原创文章,未经博主允许不得转载。 https://jerry.bl...

    Jerry Wang
  • TCP socket和web socket的区别

    小编先习惯性的看了下某中文百科网站对Web Socket的介绍,觉得很囧。如果大家按照这个答案去参加BAT等互联网公司的前端开发面试,估计会被鄙视。

    Jerry Wang
  • Linux下TCP延迟确认(Delayed Ack)机制导致的时延问题分析

    同事随手写个压力测试程序,其实现逻辑为:每秒钟先连续发N个132字节的包,然后连续收N个由后台服务回显回来的132字节包...

    潘安群
  • TMQ微信沙龙第一期回顾

    Android流畅度原理&优化 活动时间:2016年5月26日 活动介绍:微信线上交流群活动介绍TMQ微信沙龙第一期分享圆满结束啦~本次分享的主题是Androi...

    腾讯移动品质中心TMQ

扫码关注云+社区

领取腾讯云代金券