/* Example Server Code */ #include #include #include #include #include #include #include #include #include void process_request(int fd) { close(fd); } int main(int argc, char *argv[]) { struct addrinfo *ai, *runp; struct addrinfo hints; struct pollfd fds[2]; int e, nfds = 0; memset(&hints, '\0', sizeof(hints)); hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG; hints.ai_socktype = SOCK_STREAM; e = getaddrinfo(NULL, "7777", &hints, &ai); if (e != 0) error(EXIT_FAILURE, 0, "getaddrinfo: %s", gai_strerror(e)); for (runp = ai; runp != NULL && nfds < sizeof(fds) / sizeof(fds[0]); runp = runp->ai_next) { fds[nfds].fd = socket(runp->ai_family, runp->ai_socktype, runp->ai_protocol); if (fds[nfds].fd == -1) error(EXIT_FAILURE, errno, "socket"); fds[nfds].events = POLLIN; int opt = 1; setsockopt(fds[nfds].fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); if (runp->ai_family == AF_INET6) setsockopt(fds[nfds].fd, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt)); e = bind(fds[nfds].fd, runp->ai_addr, runp->ai_addrlen); if (e != 0 && errno != EADDRINUSE) { error(EXIT_FAILURE, errno, "bind"); } else if (e != 0) { close(fds[nfds].fd); continue; } e = listen(fds[nfds].fd, SOMAXCONN); if (e != 0) error(EXIT_FAILURE, errno, "listen"); nfds++; } freeaddrinfo(ai); while (1) { int i; int n = poll(fds, nfds, -1); if (n <= 0) continue; for (i = 0; i < nfds; i++) { if ((fds[i].revents & POLLIN) == 0) continue; struct sockaddr_storage rem; socklen_t remlen = sizeof(rem); int fd = accept(fds[i].fd, (struct sockaddr *) &rem, &remlen); if (fd == -1) continue; char buf1[200]; if (getnameinfo((struct sockaddr *) &rem, remlen, buf1, sizeof(buf1), NULL, 0, 0) != 0) strcpy(buf1, "???"); char buf2[100]; (void) getnameinfo((struct sockaddr *) &rem, remlen, buf2, sizeof(buf2), NULL, 0, NI_NUMERICHOST); printf("connection from %s(%s)\n", buf1, buf2); process_request(fd); printf("EOF from %s(%s)\n", buf1, buf2); } } }