| 51 | } |
| 52 | |
| 53 | void main_loop(void) { |
| 54 | fd_set fdr, fdw; |
| 55 | struct timeval tv = {0}; |
| 56 | FD_ZERO(&fdr); |
| 57 | FD_ZERO(&fdw); |
| 58 | FD_SET(server_fd, &fdr); |
| 59 | FD_SET(client_fd, &fdr); |
| 60 | FD_SET(client_fd, &fdw); |
| 61 | select(64, &fdr, &fdw, NULL, &tv); |
| 62 | |
| 63 | // client: send ping |
| 64 | if (!ping_sent && FD_ISSET(client_fd, &fdw)) { |
| 65 | if (sendto(client_fd, "ping", 4, 0, (struct sockaddr*)&dest, sizeof(dest)) == 4) { |
| 66 | ping_sent = true; |
| 67 | } |
| 68 | } |
| 69 | |
| 70 | // server: echo ping -> pong back to the sender |
| 71 | if (!pong_sent && FD_ISSET(server_fd, &fdr)) { |
| 72 | char buf[4]; |
| 73 | struct sockaddr_in src; |
| 74 | socklen_t sl = sizeof(src); |
| 75 | ssize_t n = recvfrom(server_fd, buf, sizeof(buf), 0, (struct sockaddr*)&src, &sl); |
| 76 | if (n == 4 && memcmp(buf, "ping", 4) == 0) { |
| 77 | printf("server got ping from %s:%u\n", inet_ntoa(src.sin_addr), (unsigned)ntohs(src.sin_port)); |
| 78 | sendto(server_fd, "pong", 4, 0, (struct sockaddr*)&src, sl); |
| 79 | pong_sent = true; |
| 80 | } |
| 81 | } |
| 82 | |
| 83 | // client: receive pong |
| 84 | if (ping_sent && FD_ISSET(client_fd, &fdr)) { |
| 85 | char buf[4]; |
| 86 | ssize_t n = recv(client_fd, buf, sizeof(buf), 0); |
| 87 | if (n == 4 && memcmp(buf, "pong", 4) == 0) { |
| 88 | test_success(); |
| 89 | } |
| 90 | } |
| 91 | } |
| 92 | |
| 93 | int main(void) { |
| 94 | server_fd = socket(AF_INET, SOCK_DGRAM, 0); |