#include #include #include #include #include #include #include #include #include #include #include #include #define SOBUF_SIZE 10000 #define PORT 23481 int main(int argc, char **argv) { struct sockaddr_in sin; int listenfd, connfd, pid, size, done, val, status, i; char buf[SOBUF_SIZE]; char *data; if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) err(1, "socket error"); val = SOBUF_SIZE; if (setsockopt(listenfd, SOL_SOCKET, SO_SNDBUF, &val, sizeof(val)) < 0) err(1, "setsockopt error"); val = SOBUF_SIZE; if (setsockopt(listenfd, SOL_SOCKET, SO_RCVBUF, &val, sizeof(val)) < 0) err(1, "setsockopt error"); memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons(PORT); if (bind(listenfd, (struct sockaddr *) &sin, sizeof(sin)) < 0) err(1, "bind error"); if (listen(listenfd, 1024) < 0) err(1, "listen error"); pid = fork(); if (pid == -1) err(1, "fork error"); if (pid != 0) { close(listenfd); sleep(1); if ((connfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { (void)kill(pid, SIGTERM); err(1, "parent: socket error"); } if (connect(connfd, (struct sockaddr *)&sin, sizeof(sin)) < 0) { (void)kill(pid, SIGTERM); err(1, "parent: connect error"); } for (i = 0; i < 2; i++) { data = buf; size = (i == 0 ? sizeof(buf) / 10 : sizeof(buf)); printf("parent: sending %zu bytes...\n", size); do { printf("parent: send(%zu)...\n", size); done = send(connfd, data, size, MSG_NOSIGNAL); if (done == 0) { break; } else if (done < 0) { (void)kill(pid, SIGTERM); err(1, "parent: send error"); } printf("parent: done(%zu).\n", done); data += done; size -= done; } while (size > 0); printf("parent: done.\n"); } wait(&status); if (close(connfd) < 0) { (void)kill(pid, SIGTERM); err(1, "parent: close error"); } } else { if ((connfd = accept(listenfd, (struct sockaddr *)NULL, NULL)) < 0) err(1, "child: accept error"); sleep(5); for (i = 0; i < 2; i++) { size = (i == 0 ? sizeof(buf) / 10 : sizeof(buf)); printf("child: recv(%zu, MSG_WAITALL)...\n", size); do { done = recv(connfd, buf, size, MSG_WAITALL); } while (done == -1 && errno == EINTR); if (done == 0) errx(1, "child: connection closed"); else if (done < 0) err(1, "child: recv error"); printf("child: done.\n"); } if (close(connfd) < 0) err(1, "child: close error"); } exit(0); }