zoukankan      html  css  js  c++  java
  • socket缓冲区以及阻塞模式(七)

    一、socket缓冲区

    每个 socket 被创建后,都会分配两个缓冲区,输入缓冲区和输出缓冲区。

    以下用write()/send()表示写数据/发送数据,read()/recv() 表示读数据/接收数据进行说明。

    write()/send()并不立即向网络中传输数据,而是先将数据写入缓冲区中,再由TCP协议将数据从缓冲区发送到目标机器。一旦将数据写入到缓冲区,函数就可以成功返回,不管它们有没有到达目标机器,也不管它们何时被发送到网络,这些都是TCP协议负责的事情。

    TCP协议独立于 write()/send() 函数,数据有可能刚被写入缓冲区就发送到网络,也可能在缓冲区中不断积压,多次写入的数据被一次性发送到网络,这取决于当时的网络情况、当前线程是否空闲等诸多因素,不由程序员控制。

    read()/recv()函数也是如此,也从输入缓冲区中读取数据,而不是直接从网络中读取。

    这些I/O缓冲区特性可整理如下:

    • I/O缓冲区在每个TCP套接字中单独存在;
    • I/O缓冲区在创建套接字时自动生成;
    • 即使关闭套接字也会继续传送输出缓冲区中遗留的数据;
    • 关闭套接字将丢失输入缓冲区中的数据。

    二、阻塞模式

     对于TCP套接字(默认情况下),当使用 write()/send() 发送数据时:

    • 首先会检查缓冲区,如果缓冲区的可用空间长度小于要发送的数据,那么 write()/send() 会被阻塞(暂停执行),直到缓冲区中的数据被发送到目标机器,腾出足够的空间,才唤醒 write()/send() 函数继续写入数据。
    • 如果TCP协议正在向网络发送数据,那么输出缓冲区会被锁定,不允许写入,write()/send() 也会被阻塞,直到数据发送完毕缓冲区解锁,write()/send() 才会被唤醒。
    • 如果要写入的数据大于缓冲区的最大长度,那么将分批写入。
    • 直到所有数据被写入缓冲区 write()/send() 才能返回。

    当使用 read()/recv() 读取数据时:

    •  首先会检查缓冲区,如果缓冲区中有数据,那么就读取,否则函数会被阻塞,直到网络上有数据到来。
    • 如果要读取的数据长度小于缓冲区中的数据长度,那么就不能一次性将缓冲区中的所有数据读出,剩余数据将不断积压,直到有 read()/recv() 函数再次读取。
    • 直到读取到数据后 read()/recv() 函数才会返回,否则就一直被阻塞。

    这就是TCP套接字的阻塞模式。所谓阻塞,就是上一步动作没有完成,下一步动作将暂停,直到上一步动作完成后才能继续,以保持同步性。

  • 相关阅读:
    c#代码:使用假设的方法遍历解决“谁养鱼”问题(据说是爱因斯坦所出的一道推理题) 无为而为
    远洋地暖的使用步骤
    合伙人四大原则
    model y搭载60度磷酸铁锂电池的续航表现
    model3家用充电桩按220V还是380V区别?
    食用油的挑选标准
    职责链模式(Chain of Responsibility)
    通用数据链接(UDL)的用法
    Oracle REGEXP_INSTR 用法
    访问者模式(Visitor)
  • 原文地址:https://www.cnblogs.com/myitnews/p/11433487.html
Copyright © 2011-2022 走看看