samples: net: echo_async: Better error and write handling

Initially this sample was intended to be very simple and schematic,
but as this sample going to become a base for stream API conversion,
time to handle all the edge conditions.

Signed-off-by: Paul Sokolovsky <paul.sokolovsky@linaro.org>
This commit is contained in:
Paul Sokolovsky 2018-02-21 19:28:55 +02:00 committed by Carles Cufí
commit a3a5c48d93

View file

@ -44,6 +44,12 @@ static void nonblock(int fd)
fcntl(fd, F_SETFL, fl | O_NONBLOCK); fcntl(fd, F_SETFL, fl | O_NONBLOCK);
} }
static void block(int fd)
{
int fl = fcntl(fd, F_GETFL, 0);
fcntl(fd, F_SETFL, fl & ~O_NONBLOCK);
}
int pollfds_add(int fd) int pollfds_add(int fd)
{ {
int i; int i;
@ -159,13 +165,36 @@ int main(void)
} else { } else {
char buf[128]; char buf[128];
int len = recv(fd, buf, sizeof(buf), 0); int len = recv(fd, buf, sizeof(buf), 0);
if (len == 0) { if (len <= 0) {
if (len < 0) {
printf("error: recv: %d\n", errno);
}
error:
pollfds_del(fd); pollfds_del(fd);
close(fd); close(fd);
printf("Connection fd=%d closed\n", fd); printf("Connection fd=%d closed\n", fd);
} else { } else {
/* We assume this won't be short write, d'oh */ int out_len;
send(fd, buf, len, 0); const char *p;
/* We implement semi-async server,
* where reads are async, but writes
* *can* be sync (blocking). Note that
* in majority of cases they expected
* to not block, but to be robust, we
* handle all possibilities.
*/
block(fd);
for (p = buf; len; len -= out_len) {
out_len = send(fd, p, len, 0);
if (out_len < 0) {
printf("error: "
"send: %d\n",
errno);
goto error;
}
p += out_len;
}
nonblock(fd);
} }
} }
} }