Is TCP bidirectional or full-duplex?

前端 未结 6 1680
广开言路
广开言路 2020-12-23 17:10

Bidirectional and full-duplex are different concepts. For example the Ethernet is only half-duplex because at a specific time, only on

6条回答
  •  轮回少年
    2020-12-23 17:30

    The TCP API is full-duplex. This mean that TCP API allow send data from both side of connection just in same time. Let's see the source of test program to proof:

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

    The output (on FreeBSD) is:

    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
    

    So TCP API is full-duplex and data may be sended from both side at the same time. I think that implementation is full-duplex too, but it need to write more complicated test to recognize. This is implementation dependent of course. And good implementation may does not effect when at least one transport chain link is not full-duplex.

提交回复
热议问题