From 66b7742af56362bd1651295fad84c1385194a46d Mon Sep 17 00:00:00 2001 From: Muhammad Habib Ulil A Date: Mon, 4 May 2026 15:56:20 +0700 Subject: [PATCH] feat: add TCP mode support and fix TCP speed display - Add --tcp / -T flag to explicitly select TCP protocol - Change default from UDP to TCP (use -u/--udp for UDP) - Fix test_tcp TX thread condition: was checking CMD_DIR_TX but client -t sets CMD_DIR_RX; now correctly starts TX on client transmit - Remove incorrect 0x07/0x01 header bytes from TCP TX data buffer - Replace raw hex dump in test_tcp recv loop with proper stat packet parsing using unpackStatStr + printStatStruct for human-readable speed output (e.g. Remote: Seq: 1, Rate: 85.1Mb/s) --- btest.c | 49 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 16 deletions(-) diff --git a/btest.c b/btest.c index e7edbf6..e10873c 100644 --- a/btest.c +++ b/btest.c @@ -84,6 +84,7 @@ unsigned char *calc_md5auth(unsigned char *nonce, char *passwd); char *opt_bandwidth = NULL; int opt_udpmode = 0; +int opt_tcpmode = 0; int opt_server = 0; int opt_interval = 0; int opt_nat = 0; @@ -103,6 +104,7 @@ int main(int argc, char **argv) static struct option long_options[] = { {"udp", no_argument, &opt_udpmode, 1}, + {"tcp", no_argument, &opt_tcpmode, 1}, {"transmit", no_argument, &opt_transmit, 1}, {"receive", no_argument, &opt_receive, 1}, {"server", no_argument, &opt_server, 1}, @@ -123,13 +125,16 @@ int main(int argc, char **argv) exit(1); } - while ((opt = getopt_long(argc, argv, "utrsnhdc:i:b:a:p:", long_options, &option_index)) != -1) + while ((opt = getopt_long(argc, argv, "uTtrsnhdc:i:b:a:p:", long_options, &option_index)) != -1) { switch (opt) { case 'u': opt_udpmode = 1; break; + case 'T': + opt_tcpmode = 1; + break; case 't': opt_transmit = 1; break; @@ -207,6 +212,7 @@ void usage_long() " -t, --transmit transmit data\n" " -r, --receive receive data\n" " -u, --udp use UDP\n" + " -T, --tcp use TCP (default)\n" " -b, --bandwidth #[KMG][/#] target bandwidth in bits/sec (0 for unlimited)\n" " (default %d Mbit/sec for UDP, unlimited for TCP)\n" " (optional slash and packet count for burst mode)\n" @@ -226,7 +232,8 @@ int client() char bwmult; int ret; - cmd.proto = CMD_PROTO_UDP; + /* Default to TCP unless --udp is specified */ + cmd.proto = opt_udpmode ? CMD_PROTO_UDP : CMD_PROTO_TCP; cmd.direction = opt_transmit ? CMD_DIR_RX : 0; cmd.direction += opt_receive ? CMD_DIR_TX : 0; cmd.random = 0; @@ -1062,15 +1069,11 @@ void *test_tcp_tx(void *arg) struct cmdStruct *pcmd; unsigned char *buf; - // printf("Calling test_tcp_tx()\n"); sleep(1); pcmd = (struct cmdStruct *)arg; buf = (unsigned char *)malloc(pcmd->tx_size); bzero(buf, pcmd->tx_size); - buf[0] = 0x07; - buf[4] = 0x01; - while (send(tcpSocket, buf, pcmd->tx_size, 0) > 0) ; return NULL; @@ -1079,25 +1082,39 @@ void *test_tcp_tx(void *arg) int test_tcp(struct cmdStruct cmd, int cmdsock) { pthread_t pth_tx; - // pthread_t pth_rx; - int nBytes, i; - unsigned char buffer[1024]; + int nBytes; + unsigned char buffer[2048]; + struct statStruct remoteStats; - // printf("Calling test_tcp()\n"); tcpSocket = cmdsock; - if (cmd.direction == CMD_DIR_TX) + + /* Start TX thread if we should transmit: + * - Client transmits when CMD_DIR_RX is set (client used -t flag) + * - Server transmits when CMD_DIR_TX is set (client used -r flag) */ + if (((cmd.direction & CMD_DIR_RX) && !opt_server) || + ((cmd.direction & CMD_DIR_TX) && opt_server)) { pthread_create(&pth_tx, NULL, test_tcp_tx, (void *)&cmd); } - printf("Listening on TCP cmdsock\n"); - while ((nBytes = recv(cmdsock, buffer, 1024, 0))) + /* Receive and display stat packets from the remote end */ + while ((nBytes = recv(cmdsock, buffer, sizeof(buffer), 0)) > 0) { - for (i = 0; i < nBytes - 1; i++) + int offset = 0; + while (offset + 12 <= nBytes) { - printf("%02x", buffer[i]); + if (buffer[offset] == 0x07) + { + remoteStats = unpackStatStr(buffer + offset); + printStatStruct("Remote: ", &remoteStats); + fflush(stdout); + offset += 12; + } + else + { + offset++; + } } - printf("\n"); } return 0; }