【问题标题】:tcp underlying transmission mechanism/ network programmingtcp底层传输机制/网络编程
【发布时间】:2010-11-18 22:09:11
【问题描述】:


我已经搜索过,但找不到以下内容:
Process1 通过 TCP 套接字传输数据。进行传输的代码是(伪代码)

//Section 1
write(sock,data,len);//any language.Just write data
//Section 2

写入后的Process1可以在第2节继续,但这并不意味着数据已经传输完毕。 TCP 可以缓冲数据以供以后传输。
现在 Process2 与 Process1 同时运行。两个进程都尝试同时发送数据。 IE。两者都将具有上述代码。
问题1:如果两个进程同时将数据写入 TCP 套接字,数据最终将如何通过 IP/OS 通过线路传输?
a) Process1 的所有数据后跟 Process2 的所有数据(或反向),即一些 FIFO 顺序?

b) 来自 Process1 和 Process2 的数据将由 IP 层(或操作系统)通过网络进行多路复用,并“同时”发送?
问题 2: 例如,如果我添加了延迟,我是否可以确定来自 2 个进程的数据是通过网络串行发送的(例如,Process1 的所有数据后跟 Process2 的所有数据)?
更新:
Process1 和 Process2 不是父子。他们也在不同的套接字上工作
谢谢

【问题讨论】:

    标签: language-agnostic networking network-programming tcp


    【解决方案1】:

    嗯,您是在谈论由两个进程(如父进程和子进程)共享的单个套接字吗?在这种情况下,数据将按输出系统调用的顺序进行缓冲 (write(2)s)。

    如果更可能的是,您在两个进程中谈论两个不相关的 TCP 套接字,则无法保证数据到达线路的任何顺序。原因是套接字可能连接到以不同速度消耗数据的远程点。 TCP flow control 然后确保快速发送方不会压倒慢速接收方。

    【讨论】:

    • 但是输出系统调用的顺序必须明确控制,否则就变得不确定了。
    • 是的,但那是完全不同的讨论。
    • @Nikolai N Fetissov:所以操作系统系统调用的行为不是确定性的分析?
    • TCP 堆栈是一个非常复杂的野兽。从应用程序的角度来看,您可以假设它不是确定性的 :)
    • @Nikolai N Fetissov:但是是 TCP 还是 IP 做的? TCP 将数据传递给 IP。所以 IP 也是黑盒?
    【解决方案2】:

    答案 1:未指定顺序,至少在我见过的支持套接字的操作系统上是这样。流程 1 和 2 应设计为合作,例如通过在套接字上共享一个锁/互斥锁。

    答案 2:如果您的意思是固定时间延迟,则不是。相反,让进程 1 向进程 2 发出继续信号,指示进程 1 已完成发送。在进程间通信方面使用管道、本地套接字、信号、共享内存或操作系统提供的任何东西。仅在"flushing" the socket 之后发送信号(实际上并没有刷新)。

    【讨论】:

    • @larsmans:所以 write,flush,signal.Flushing 保证将所有数据传输到目的地,或者就像例如在 C++ I/O 操作中?只有一个信号给操作系统刷新。不保证会发生
    • 这可能取决于您的操作系统,但无论如何,数据在进程 2 开始写入之前就在内核缓冲区中,因此很可能会将数据推送到网络上。
    • @user384706,不,很多人不这样做,他们只是等待操作系统发送数据。有时会启用 TCP_NODELAY(防止某些缓冲)以提高性能,但这并不总是有帮助。
    • @user384706,请阅读我链接到的帖子,它解释了套接字上没有刷新操作。
    • @larsmans:我阅读了链接。您是什么意思“它解释了套接字上没有刷新操作”?它说使用刷新,缓冲区中尚未发送的数据被发送。 TCP_NODELAY 如何适应?它没有提到这个
    【解决方案3】:

    一个 TCP 套接字由一个元组标识,该元组通常至少是(源 IP、源端口、目标 IP、目标端口)。不同的套接字有不同的标识元组。

    现在,如果您在两个进程上使用同一个套接字,这取决于 write(2) 调用的顺序。但是,您应该考虑到 write(2) 可能不会消耗您传递给它的所有数据,发送缓冲区可能已满,导致短写入(write()'ing 少于要求,并返回作为返回值写入的字节数),导致 write() 阻塞/休眠,直到有一些缓冲区空间,或者导致 write() 返回 EAGAIN/EWOULDBLOCK 错误(对于非阻塞套接字)。

    【讨论】:

    • 我说的是每个进程的不同套接字。你的意思是进程可能会阻塞,第二次开始写入并发生交错?
    • @user384706:如果它们是不同的套接字,那并不重要。每个 TCP 段都包含源端口和目标端口,因此即使您的 TCP/IP 堆栈一次发送 1 个字节的数据,也不会发生混淆。
    • 我知道它们不能混用。我的问题是我将通过线路看到的消息流是什么。多路复用还是串行传输?
    • @user384706:你永远不知道。取决于很多东西,主要是网络条件和操作系统的 TCP/IP 堆栈。
    【解决方案4】:
    1. write() 是原子的;同上 send() 和朋友。无论哪个先执行,都会传输其所有数据,而另一个会阻塞。
    2. 延迟是不必要的,参见 (1)。

    编辑:但是如果我现在看到您在谈论每个进程的不同套接字,那么您的问题似乎毫无意义。应用程序无法知道 TCP 是如何使用网络的,那么这有什么关系呢? TCP 将按照它认为合适的顺序以最多一个 MTU 的数据包进行传输。

    【讨论】:

    • 你是说如果 Process1 调用 write 在例如时间戳 1:00:00 和 Process2 调用 write 2 秒后,仍然不确定数据包是否会被复用或 Process1 的传输是否已经完成?
    • 显然有一点在传输时间短或间隔时间长的情况下问题变得荒谬。我仍然不知道为什么这对你很重要。从某种意义上说,这个问题本质上是荒谬的。
    猜你喜欢
    • 2011-05-09
    • 2013-08-14
    • 2012-10-31
    • 1970-01-01
    • 1970-01-01
    • 2010-12-27
    • 1970-01-01
    • 1970-01-01
    • 2020-08-10
    相关资源
    最近更新 更多