diff --git a/src/iperf_server_api.c b/src/iperf_server_api.c index 31b642e..5d3e3c2 100644 --- a/src/iperf_server_api.c +++ b/src/iperf_server_api.c @@ -534,8 +534,14 @@ iperf_run_server(struct iperf_test *test) FD_SET(s, &test->read_set); if (s > test->max_fd) test->max_fd = s; - // If the protocol isn't UDP, set nonblocking sockets - if (test->protocol->id != Pudp) { + /* + * If the protocol isn't UDP, or even if it is but + * we're the receiver, set nonblocking sockets. + * We need this to allow a server receiver to + * maintain interactivity with the control channel. + */ + if (test->protocol->id != Pudp || + !test->sender) { setnonblocking(s, 1); } diff --git a/src/iperf_udp.c b/src/iperf_udp.c index edc1721..5bb8afe 100644 --- a/src/iperf_udp.c +++ b/src/iperf_udp.c @@ -63,7 +63,12 @@ iperf_udp_recv(struct iperf_stream *sp) r = Nread(sp->socket, sp->buffer, size, Pudp); - if (r < 0) + /* + * If we got an error in the read, or if we didn't read anything + * because the underlying read(2) got a EAGAIN, then skip packet + * processing. + */ + if (r <= 0) return r; sp->result->bytes_received += r;