【问题标题】:Sockets: what happens when the program is not blocked on read() message is received套接字:当程序在收到 read() 消息时没有被阻塞时会发生什么
【发布时间】:2016-10-10 01:24:00
【问题描述】:

在 Socket 编程中,无论您是在 C 还是 java 中编写代码,都假设以下情况。

客户端的代码类似于:

while(1) {
    read(...);
    /* process received msg */
    process(received_msg)
}

现在,客户端收到msg1 并忙于处理它。这意味着处理器现在正在process() 中运行一些指令。此时,msg2 到达。但是,现在没有read() 阻止接收它。现在收到的消息msg2 会发生什么?

它取决于协议吗?是否依赖于语言api?

我认为如果我每次收到消息都创建一个新线程,我可以克服这个问题。我的问题旨在了解在单线程上下文中会发生什么,以及是否有任何方法可以在不使用多线程的情况下完成这项工作。

【问题讨论】:

  • 内核为你缓冲接收到的数据,以便下次读取时可用。如果内核无法再缓冲以及其他此类情况,内核还会管理发生的情况(取决于协议)。
  • 如果你的消息适合套接字的缓冲区,你会在那里找到它。如果缓冲区已满,您的 TCP 堆栈——(因为套接字是流式传输的,因此是 TCP)——将通知发送方保留这些数据包。另请参阅 SO what happens when I write data to a blocking socket, faster than the other side reads?
  • "如果有任何方法可以在不使用多个线程的情况下完成这项工作。" - 在 单线程同步处理 方法中,如果您的处理器比发送方慢并且您使用 TCP,那么您也会以减慢发送方的速度结束。当多线程不可用时,UNIX-es 会为每个请求派生/派生另一个进程。

标签: java c sockets


【解决方案1】:

现在传入的消息 msg2 会发生什么?

它被缓冲了。

是否依赖于协议?

我描述的是 TCP,但 UDP 也是如此。但是,对于 TCP 和 UDP,缓冲区填充时的行为是不同的: TCP 使发送方停止; UDP 丢弃下一个数据报。

是否依赖于语言 api?

没有。

我认为如果我每次收到消息都创建一个新线程,我可以解决这个问题。

没有需要克服的问题。

【讨论】:

  • >> 没有需要克服的问题 - 实际上有一个问题。如果接收方读取的速度比发送方发送的速度慢,则发送方可能会面临超时,接收方将丢失最新收到的数据包中的所有内容。最好让一个线程在堆中而不是在操作系统的 TCP 缓冲区中进行缓冲,并由其他线程来处理它。在这里,开发人员将能够决定堆缓冲区大小以满足任务要求。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-29
  • 2012-07-31
  • 2015-12-25
相关资源
最近更新 更多