/* Modified version of yesterday's discussion section code, which is in turn * derived from Beej's guide -- see there for more explanation: * http://beej.us/guide/bgnet/output/html/multipage/clientserver.html * * * This verison demonstrates what happens when the client abruptly * closes a connection, and how to deal with it. */ #include #include #include #include #include #include #include #include #include #include #include #define PORT "31338" // the port users will be connecting to #define BACKLOG 10 // how many pending connections queue will hold #define BUFFER_LEN 100 // get sockaddr, IPv4 or IPv6: void *get_in_addr(struct sockaddr *sa) { if (sa->sa_family == AF_INET) { return &(((struct sockaddr_in*)sa)->sin_addr); } return &(((struct sockaddr_in6*)sa)->sin6_addr); } int main(void) { // Ignore SIGPIPE // signal(SIGPIPE, SIG_IGN); int sockfd, new_fd; // listen on sock_fd, new connection on new_fd struct addrinfo hints, *servinfo, *p; struct sockaddr_storage their_addr; // connector's address information socklen_t sin_size; int yes=1; char s[INET6_ADDRSTRLEN]; int rv; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; // use my IP if ((rv = getaddrinfo(NULL, PORT, &hints, &servinfo)) != 0) { fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv)); return 1; } // loop through all the results and bind to the first we can for(p = servinfo; p != NULL; p = p->ai_next) { if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("server: socket"); continue; } if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { perror("setsockopt"); exit(1); } if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) { close(sockfd); perror("server: bind"); continue; } break; } if (p == NULL) { fprintf(stderr, "server: failed to bind\n"); return 2; } freeaddrinfo(servinfo); // all done with this structure if (listen(sockfd, BACKLOG) == -1) { perror("listen"); exit(1); } while (1) { // main accept() loop sin_size = sizeof(their_addr); printf("server: waiting for connections...\n"); new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size); if (new_fd == -1) { perror("accept"); continue; } inet_ntop(their_addr.ss_family, get_in_addr((struct sockaddr *)&their_addr), s, sizeof(s)); printf("Boy oh boy! I got a connection from %s\n", s); int res = 0; while(res >= 0) { char* str = "Hi there!\n"; res = write(new_fd, str, strlen(str)); printf("Write returned %d\n", res); sleep(1); } } return 0; }