#include #include #include #include #include #include #include #include #include #include #include #include int main() { struct addrinfo hints; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = 0; hints.ai_protocol = 0; struct addrinfo *result; int ret = getaddrinfo("127.0.0.1", "24242", &hints, &result); if (ret == -1) { err(EXIT_FAILURE, "failed getting addr info"); } int tcp_sock = -1; for (struct addrinfo *rp = result; rp != NULL; rp = rp->ai_next) { int s = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); if (s == -1) continue; if (connect(s, rp->ai_addr, rp->ai_addrlen) != -1) { tcp_sock = s; break; } close(s); } freeaddrinfo(result); if (tcp_sock == -1) { err(EXIT_FAILURE, "couldn't connect to socket"); return -1; } ret = fcntl(tcp_sock, F_SETFL, O_NONBLOCK); if (ret == -1) { close(tcp_sock); return ret; } struct pollfd polls[2] = {{ .fd = STDIN_FILENO, .events = POLLIN }, { .fd = tcp_sock, .events = POLLIN } }; while (poll(polls, 2, -1)) { if (polls[0].revents) { char cb = 'a'; int ret = read(STDIN_FILENO, &cb, 1); if (ret == -1) { err(EXIT_FAILURE, "failed reading from stdio"); } if (ret == 0) { break; } ret = write(tcp_sock, &cb, 1); if (ret == -1) { err(EXIT_FAILURE, "failed writing to socket"); } } if (polls[1].revents) { if (polls[1].revents & POLLHUP) { printf("Closed socket\n"); break; } char buf[4096]; int ret = read(tcp_sock, buf, 4096 - 1); if (ret == -1 && errno != EWOULDBLOCK) { err(EXIT_FAILURE, "failed reading from socket"); } if (ret == 0) { printf("Closed socket\n"); break; } buf[ret] = '\0'; printf("%s\n", buf); } } close(tcp_sock); }