TCP双向还是全双工?

smw*_*dia 30 sockets tcp duplex

Bidirectional并且full-duplex是不同的概念.例如,Ethernet只有半双工,因为在特定时间,只有一个主机可以通过线路发送数据,并且它不能同时发送和接收数据.

因此,当我们通过以太网使用TCP时,我认为TCP只是双向或半双工.

在这里它说TCP是全双工的.为什么?

Raz*_*van 23

它当然是双向的,因为双方都发送/接收数据包.当您询问TCP是否为全双工时,您究竟是什么意思?

发送和接收的分组在同一时间有更多的是与物理器件,而TCP是定义数据应该如何被成帧和为了到达目的地处理的协议.

NIC(网络接口控制器)负责发送和接收物理数据包,您必须检查有关半/全双工功能的信息.

例如,如果无线(802.11)使用相同的天线来发送和接收无线电信号,则它是半双工的.

  • 我认为它们指的是TCP协议支持全双工通信的事实. (2认同)

use*_*421 21

这两者都是.它是双向的,因为它可以在两个方向上发送数据,并且它是全双工的,因为它可以在API级别同时执行此操作,而无需线路转换.

当然,在较低级别,它可能受到可用物理层的限制.


okl*_*las 7

TCP API是全双工的.这意味着TCP API允许同时从连接的两端发送数据.让我们看一下测试程序的来源来证明:

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>


void do_write(const char* who, int socket) {
    const char hello[] = "hello!";
    if( 0 < write(socket, hello, strlen(hello)) )
        printf( "%s: write done ok\n", who );
    else
        printf( "%s: write error: %s\n", who, strerror(errno) );
}

void do_read(const char* who, int socket) {
    /* do parental things with this end, like reading the child's message */
    char buf[1024];
    int n = read(socket, buf, sizeof(buf));
    if( 0 < n )
        printf("%s: received '%.*s' %db\n", who, n, buf, n);
    else if( 0 == n )
        printf( "%s: no data available\n", who );
    else
        printf( "%s: read error: %s\n", who, strerror(errno) );
}

int main() {
    int fd[2];
    static const int parent = 0;
    static const int child = 1;
    pid_t pid;

    socketpair(PF_LOCAL, SOCK_STREAM, 0, fd);

    pid = fork();
    if (pid == 0) {      /* child process */
        close(fd[parent]);
        do_write("child", fd[child]);
        do_read("child", fd[child]);
        /* sleep(1); */
        do_write("child", fd[child]);
        do_read("child", fd[child]);
    } else {             /* parent process */
        close(fd[child]);
        do_write("parent", fd[parent]);
        do_read("parent", fd[parent]);
        do_write("parent", fd[parent]);
        do_read("parent", fd[parent]);
    }

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出(在FreeBSD上)是:

parent: write done ok
child: write done ok
child: received 'hello!' 6b
child: write done ok
parent: received 'hello!hello!' 12b
parent: write done ok
child: received 'hello!' 6b
parent: no data available
Run Code Online (Sandbox Code Playgroud)

因此TCP API是全双工的,并且可以同时从两侧发送数据.我认为实现也是全双工,但它需要编写更复杂的测试来识别.这当然取决于实现.当至少一个传输链路不是全双工时,良好的实现可能不会产生影响.

  • 这不是"来源",它是您编写的测试程序. (3认同)

Abh*_*rma 7

是的,TCP 连接提供全双工服务。让我们了解全双工的含义。这意味着同时在两个实体之间交换数据(发送和接收)。由于 TCP 是一种传输层协议,传输层协议提供运行在不同主机上的进程之间的逻辑通信,因此这里全双工的含义也是在这方面。

这里全双工的意思是“如果在一台主机上的进程 A 和另一台主机上的进程 B 之间存在 TCP 连接,那么应用层数据可以从进程 A 流向进程 B,同时应用层数据从进程 B 流向进程 B。过程 A”。TCP 连接也始终是点对点的,即在单个发送方和单个接收方之间。请记住,来自进程 A 的数据尚未通过传输层以下的层,类似地,来自进程 B 的数据将通过传输层以下的层。

资料来源:Kurose、Ross 的计算机网络。


Agi*_*gis 6

通过阅读您发布的文章,我认为很明显他们在谈论支持全双工通信的TCP (重点是我的):

[TCP] 是一种全双工协议,意味着每个 TCP 连接支持一对字节流,一个在每个方向上流动。


Gab*_*les 6

概括

TCP是一个支持全双工的软件层,但不保证它。如果物理硬件层只是半双工以太网,那么从技术上讲,您将在硬件层获得时间切片半双工,即使 TCP 软件层不知道其中的差异。

所以,如果硬件支持的话,那么TCP就是真正的全双工。如果硬件只是半双工,那么 TCP软件的行为就像全双工一样,因为它允许“同时”双向通信,但从技术上讲,它只是半双工。

回到上面第一段:因此,TCP是一个支持全双工的软件层,但不保证它。

以太网在物理硬件层可以是半双工全双工

然而,从 10BASE-T [10 Mbps] 标准开始的现代以太网显然现在是真正的全双工。请参阅此处:https: //en.wikipedia.org/wiki/Ethernet(已添加重点):

此外,10BASE-T [ 10 Mbps ] 标准引入了全双工操作模式,该模式在快速以太网[ 100 Mbps ]中变得常见,并且成为千兆位以太网[ 1000 Mbps ]的事实上的标准。在全双工中,交换机和站可以同时发送和接收,因此现代以太网是完全无冲突的。

在这两种情况下:无论物理硬件层是半双工还是全双工,TCP 仍然是双向的。

更复杂的是,显然所有以太网标准都定义了全双工和半双工通信选项,但“任何现有硬件都不支持千兆位速度的半双工操作”。请参阅此处: https: //en.wikipedia.org/wiki/Ethernet_over_twisted_pa ​​ir#Autonegotiation_and_duplex(添加了重点):

自动协商和双工

双绞线以太网标准直至千兆位以太网定义了全双工和半双工通信。然而,任何现有硬件都不支持千兆位速度的半双工操作。[27][28] 更高速度的标准,2.5GBASE-T 至 40GBASE-T[29],运行速度为 2.5 至 40 Gbit/s,因此仅定义了通常通过网络交换机连接的全双工点对点链路,并且不支持传统的共享介质 CSMA/CD 操作。[30]

双绞线以太网存在多种不同的操作模式(10BASE-T半双工、10BASE-T全双工、100BASE-TX半双工等),并且大多数网络适配器都支持不同的操作模式。为了建立有效的 1000BASE-T 连接,需要自动协商。

我刚刚了解到的更多有趣的花絮

我一直想知道:“‘BASE’在 10BASE-T、100BASE-T 等中到底意味着什么?”

回答:

https://en.wikipedia.org/wiki/Classic_Ethernet

在10BASE-X中,10代表其最大吞吐量10Mbit/s,BASE表示其使用基带传输,X表示所使用的介质类型。

并且: https: //en.wikipedia.org/wiki/Baseband

带信号低通信号是一种与其最高频率相比可以包含非常接近于零的频率的信号(例如,声音波形可以被视为基带信号,而无线电信号或任何其他调制信号则可以被视为基带信号)。不是)。

因此,“BASE”意味着它使用基带信号,基带信号被定义为可以从 0 Hz 到 cutoff_freq Hz 的低通信号,而不是在特定通带内变化的调频 (FM) 信号例如,(相对于基带)x Hz 到 y Hz 的范围。FM 广播是通带信号,而不是基带信号。显然,以太网是一种基带信号。

另请参阅: https: //en.wikipedia.org/wiki/Passband

T代表“双绞线”,如用于传输信号的双绞线。请参阅: https: //www.techtarget.com/searchnetworking/definition/10BASE-T

10BASE-T 是 IEEE 指定的简写标识符。10表示最大传输速度为10Mbps BASE是指基带信令,也就是说它只能在介质上承载以太网信号。T指的是双绞线中的双绞线。