Sockets TCP是双向的还是全双工的?

Sockets TCP是双向的还是全双工的?,sockets,tcp,duplex,Sockets,Tcp,Duplex,双向和全双工是不同的概念。例如,以太网仅为半双工,因为在特定时间,只有一台主机可以通过线路发送数据,并且不能同时发送和接收数据 所以,当我们在以太网上使用TCP时,我认为TCP只是双向或半双工的 但是它说TCP是全双工的。为什么?这肯定是双向的,因为双方都发送/接收数据包。当你问TCP是否为全双工时,你的确切意思是什么 同时发送和接收数据包与物理组件的关系更大,而TCP是一种协议,定义了数据应该如何帧化和处理以到达目的地 NIC(网络接口控制器)负责发送和接收物理数据包,您必须在那里检查半/全双

双向
全双工
是不同的概念。例如,
以太网
仅为半双工,因为在特定时间,只有一台主机可以通过线路发送数据,并且不能同时发送和接收数据

所以,当我们在以太网上使用TCP时,我认为TCP只是双向或半双工的


但是它说TCP是全双工的。为什么?

这肯定是双向的,因为双方都发送/接收数据包。当你问TCP是否为全双工时,你的确切意思是什么

同时发送和接收数据包与物理组件的关系更大,而TCP是一种协议,定义了数据应该如何帧化和处理以到达目的地

NIC(网络接口控制器)负责发送和接收物理数据包,您必须在那里检查半/全双工功能


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

两者都是。它是双向的,因为它可以在两个方向上发送数据;它是全双工的,因为它可以在API级别同时发送数据,而不需要线路转换


当然,在较低的层次上,它可能会受到可用物理层的限制。

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

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


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;
}

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

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

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


资料来源:罗斯库罗斯的计算机网络。

这取决于你在思考哪一层。在物理层上,它取决于介质、电信号的传输方式;如果您从传输层考虑,它是全双工的,因为每个对等方都可以根据需要同时发送和接收。

现代以太网是全双工的。@YuHao谢谢,但是如果在旧的半双工以太网环境中呢?TCP是如何适应的?TCP作为一种“传输层协议”提供了一个到上层的双向通道,我认为应该从这个角度来看。TCP不关心IP层下面的层做什么或不做什么,只要它们可以移动IP数据报。TCP当然可以是全双工的,其中,两台主机可以在同一时刻生成数据报。然而,真正决定这些数据报(现在是帧)能否以全双工方式交换的是MAC层和PHY层。谢谢。所以我认为双工这个词并不适用于TCP。因此,本教程()并不确切地说,TCP是全双工的。我认为它们指的是TCP协议支持全双工通信的事实。不需要单独的主机,甚至不需要单独的进程。这不是“源”,而是您编写的测试程序。测试程序的源并不能证明任何事情。问题是关于TCP。问题中没有出现“API”一词。
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