web-dev-qa-db-ja.com

TCP双方向または全二重?

Bidirectionalおよびfull-duplexは異なる概念です。たとえば、Ethernetは半二重のみです。これは、特定の時間に1つのホストだけが回線を介してデータを送信でき、同時にデータを送受信できないためです

したがって、イーサネット経由でTCP=を使用する場合、TCPは双方向または半二重のみです。

しかし ここ はTCPは全二重です。なぜですか?

26
smwikipedia

両者はパケットを送受信するため、確かに双方向です。 TCP is全二重ですか?

パケットの送信と受信の両方同時には物理的なコンポーネントと関係がありますが、TCPは、目的地に到着します。

NIC(ネットワークインターフェイスコントローラー)は物理パケットの送受信を担当し、半二重/全二重の機能について確認する必要があります。

たとえば、ワイヤレス(802.11)は、無線信号の送受信に同じアンテナを使用している場合、半二重です。

20
Razvan

両方です。それは双方向にデータを送信できるため双方向であり、APIレベルで回線の切り替えを必要とせずに同時に行うことができるため、全二重です。

もちろん、より低いレベルでは、利用可能な物理層によって制限される場合があります。

20
user207421

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

出力(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

TCP APIは全二重であり、データは両側から同時に送信される可能性があります。実装も全二重であると思いますが、認識するにはより複雑なテストを記述する必要があります。もちろん、これは実装依存であり、少なくとも1つのトランスポートチェーンリンクが全二重ではない場合、適切な実装は影響しない場合があります。

7
oklas

あなたが投稿した記事を読むことで、彼らがTCPsupporting全二重通信について話していることは明らかだと思います(エンファシス鉱山):

[TCP]は全二重プロトコルです。つまり、各TCP接続サポート各方向に流れる1つのバイトストリームのペアです。

4
Agis

はい、TCP接続は全二重サービスを提供します。全二重の意味を理解しましょう。 2つのエンティティ間で同時にデータを交換(送信と受信)することを意味します。 TCPはトランスポート層プロトコルであり、トランスポート層プロトコルは異なるホストで実行されているプロセス間の論理通信を提供するため、この点でも全二重の意味があります。

ここで全二重"あるホストのプロセスAと別のホストのプロセスBの間にTCP接続がある場合、アプリケーション層のデータはプロセスから流れることができますアプリケーション層のデータがプロセスBからプロセスAに流れると同時に、プロセスAからプロセスBへ。 A TCP接続も常にポイントツーポイント、つまり、単一の送信者と単一の受信者の間です。プロセスAからのデータはまだトランスポートレイヤーの下のレイヤーを通過していません。同様に、プロセスBからのデータはトランスポートレイヤーの下のレイヤーを通過します。

出典:コンピューターネットワーキング、黒瀬、ロス

3
Abhishek Sharma

どのレイヤーを考えているかによります。物理層では、メディア、電気信号の送信方法に依存します。トランスポート層から考えると、各ピアは必要に応じて同時に送受信できるため、全二重です。

1
codewarrior