diff --git a/configure.ac b/configure.ac
index 2ff58266..72d736b3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -125,7 +125,7 @@ AC_CHECK_DECLS([__CYGWIN__])
 AC_SEARCH_LIBS(accept, network socket)
 
 # Checks for library functions.
-AC_CHECK_FUNCS([accept4 gai_strerror getaddrinfo gettimeofday select socket strerror strlcpy])
+AC_CHECK_FUNCS([accept4 gai_strerror getaddrinfo gettimeofday select socket strerror strlcpy setvbuf])
 
 # Required for MinGW with GCC v4.8.1 on Win7
 AC_DEFINE(WINVER, 0x0501, _)
diff --git a/src/modbus.c b/src/modbus.c
index af3e9781..2517efd7 100644
--- a/src/modbus.c
+++ b/src/modbus.c
@@ -427,6 +427,8 @@ int _modbus_receive_msg(modbus_t *ctx, uint8_t *msg, msg_type_t msg_type)
                 wsa_err = WSAGetLastError();
 
                 // no equivalent to ETIMEDOUT when select fails on Windows
+                // but we still need it to forget the invalid answer
+                modbus_flush(ctx);
                 if (wsa_err == WSAENETDOWN || wsa_err == WSAENOTSOCK) {
                     modbus_close(ctx);
                     modbus_connect(ctx);
diff --git a/tests/unit-test-client.c b/tests/unit-test-client.c
index b3ac76fa..527940c9 100644
--- a/tests/unit-test-client.c
+++ b/tests/unit-test-client.c
@@ -98,6 +98,16 @@ int main(int argc, char *argv[])
 
     memset(last_test_title, 0, sizeof(last_test_title));
 
+#ifdef _WIN32
+# ifdef HAVE_SETVBUF
+    // auto-flush so logs are comprehensible when the
+    // same console collects output of server and client
+    // https://stackoverflow.com/a/214292/4715872
+    setvbuf(stdout, NULL, _IOLBF, 0);
+    setvbuf(stderr, NULL, _IOLBF, 0);
+# endif
+#endif
+
     if (argc > 1) {
         if (strcmp(argv[1], "tcp") == 0) {
             use_backend = TCP;
@@ -288,6 +298,10 @@ int main(int argc, char *argv[])
                                                           : UT_INPUT_REGISTERS_NB;
     memset(tab_rp_registers, 0, nb_points * sizeof(uint16_t));
 
+    /* Wait remaining bytes before flushing */
+    usleep(1000000);
+    modbus_flush(ctx);
+
     TEST_TITLE("4/5 modbus_write_and_read_registers");
     /* Write registers to zero from tab_rp_registers and store read registers
        into tab_rp_registers. So the read registers must set to 0, except the
@@ -721,13 +735,46 @@ int main(int argc, char *argv[])
         /* Wait remaining bytes before flushing */
         usleep(11 * 5000);
         modbus_flush(ctx);
+        /* ...and then some, just in case (e.g. kernel delays, clock jitter, multi-CPU...) */
+        usleep(1000000);
+        modbus_flush(ctx);
 
         /* Timeout of 7ms between bytes */
-        TEST_TITLE("2/2 Adapted byte timeout (7ms > 5ms)");
+        TEST_TITLE("2/2-A Adapted byte timeout (7ms > 5ms)");
         modbus_set_byte_timeout(ctx, 0, 7000);
         rc = modbus_read_registers(
             ctx, UT_REGISTERS_ADDRESS_BYTE_SLEEP_5_MS, 1, tab_rp_registers);
-        ASSERT_TRUE(rc == 1, "FAILED (rc: %d != 1)", rc);
+        if (rc == 1) {
+            ASSERT_TRUE(rc == 1, "FAILED (rc: %d != 1)", rc);
+        } else {
+            /* Timeout of 20ms between bytes, allow for 2*16+1
+             * Windows sleep seems to be at least 15ms always.
+             */
+            usleep(1000000);
+            modbus_flush(ctx);
+            TEST_TITLE("2/2-B Adapted byte timeout (33ms > 20ms)");
+            modbus_set_byte_timeout(ctx, 0, 33000);
+            rc = modbus_read_registers(
+                ctx, UT_REGISTERS_ADDRESS_BYTE_SLEEP_20_MS, 1, tab_rp_registers);
+
+            if (rc == 1) {
+                ASSERT_TRUE(rc == 1, "FAILED (rc: %d != 1)", rc);
+            } else {
+                /* For some reason, FreeBSD 12 and OpenBSD 6.5 also
+                 * tended to fail with 7ms and even 33ms variants
+                 * as "gmake check", but passed in
+                 * gmake -j 8 && ( ./tests/unit-test-server|cat & sleep 1 ; ./tests/unit-test-client|cat )
+                 * An even longer timeout seems to satisfy all of them.
+                 */
+                usleep(1000000);
+                modbus_flush(ctx);
+                TEST_TITLE("2/2-C Adapted byte timeout (66ms > 20ms)");
+                modbus_set_byte_timeout(ctx, 0, 66000);
+                rc = modbus_read_registers(
+                    ctx, UT_REGISTERS_ADDRESS_BYTE_SLEEP_20_MS, 1, tab_rp_registers);
+                ASSERT_TRUE(rc == 1, "FAILED (rc: %d != 1)", rc);
+            }
+        }
     }
 
     /* Restore original byte timeout */
diff --git a/tests/unit-test-server.c b/tests/unit-test-server.c
index ea4455f1..1aab0d43 100644
--- a/tests/unit-test-server.c
+++ b/tests/unit-test-server.c
@@ -44,6 +44,16 @@ int main(int argc, char *argv[])
     int header_length;
     char *ip_or_device = NULL;
 
+#ifdef _WIN32
+# ifdef HAVE_SETVBUF
+    // auto-flush so logs are comprehensible when the
+    // same console collects output of server and client
+    // https://stackoverflow.com/a/214292/4715872
+    setvbuf(stdout, NULL, _IOLBF, 0);
+    setvbuf(stderr, NULL, _IOLBF, 0);
+# endif
+#endif
+
     if (argc > 1) {
         if (strcmp(argv[1], "tcp") == 0) {
             use_backend = TCP;
@@ -169,6 +179,9 @@ int main(int argc, char *argv[])
 
     for (;;) {
         do {
+#ifdef _WIN32
+            fflush(stdout);
+#endif
             rc = modbus_receive(ctx, query);
             /* Filtered queries return 0 */
         } while (rc == 0);
@@ -208,7 +221,7 @@ int main(int argc, char *argv[])
             } else if (address == UT_REGISTERS_ADDRESS_SLEEP_500_MS) {
                 printf("Sleep 0.5 s before replying\n");
                 usleep(500000);
-            } else if (address == UT_REGISTERS_ADDRESS_BYTE_SLEEP_5_MS) {
+            } else if (address == UT_REGISTERS_ADDRESS_BYTE_SLEEP_5_MS || address == UT_REGISTERS_ADDRESS_BYTE_SLEEP_20_MS) {
                 /* Test low level only available in TCP mode */
                 /* Catch the reply and send reply byte a byte */
                 uint8_t req[] = "\x00\x1C\x00\x00\x00\x05\xFF\x03\x02\x00\x00";
@@ -223,7 +236,11 @@ int main(int argc, char *argv[])
                 req[1] = query[1];
                 for (i = 0; i < req_length; i++) {
                     printf("(%.2X)", req[i]);
-                    usleep(5000);
+                    if (address == UT_REGISTERS_ADDRESS_BYTE_SLEEP_5_MS) {
+                        usleep(5000);
+                    } else if (address == UT_REGISTERS_ADDRESS_BYTE_SLEEP_20_MS) {
+                        usleep(20000);
+                    }
                     rc = send(w_s, (const char *) (req + i), 1, MSG_NOSIGNAL);
                     if (rc == -1) {
                         break;
@@ -250,6 +267,9 @@ int main(int argc, char *argv[])
             }
         }
 
+#ifdef _WIN32
+        fflush(stdout);
+#endif
         rc = modbus_reply(ctx, query, rc, mb_mapping);
         if (rc == -1) {
             break;
diff --git a/tests/unit-test.h.in b/tests/unit-test.h.in
index 3d83967a..d6427c59 100644
--- a/tests/unit-test.h.in
+++ b/tests/unit-test.h.in
@@ -54,8 +54,11 @@ const uint16_t UT_REGISTERS_ADDRESS_SPECIAL = 0x170;
 const uint16_t UT_REGISTERS_ADDRESS_INVALID_TID_OR_SLAVE = 0x171;
 /* The server will wait for 1 second before replying to test timeout */
 const uint16_t UT_REGISTERS_ADDRESS_SLEEP_500_MS = 0x172;
-/* The server will wait for 5 ms before sending each byte */
+/* The server will wait for 5 ms before sending each byte
+ * WARNING: this may be too short for WIN32 */
 const uint16_t UT_REGISTERS_ADDRESS_BYTE_SLEEP_5_MS = 0x173;
+/* The server will wait for 20 ms before sending each byte */
+const uint16_t UT_REGISTERS_ADDRESS_BYTE_SLEEP_20_MS = 0x174;
 
 /* If the following value is used, a bad response is sent.
    It's better to test with a lower value than