Bidirectional
and full-duplex
are different concepts. For example the Ethernet
is only half-duplex because at a specific time, only on
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.