/* * An modified example of server using TCP protocol. * (UNIX NETWORK PROGRAMMING, by Richard Stevens, * Prentice Hall, 1990, pp. 284-286) * * The program forks a process for each cli program. * It reads one message from a socket which is connected * with the cli program. It prints out the message on the stderr, * modifies the message, and sends the message back to the cli program. Also, it uses a select statement to choose between read() and recv(). This is because it is upgraded to be able to receive out of band data. */ #include #include #include #include #include #include #include #include #include #include #include #include #include "message.h" #define SERV_HOST_ADDR "156.12.127.18" /* acad's Internet address, defined in /etc/hosts */ #define PORT 15010 #define BACKLOG 15010 extern int errno; void sigurg_handler(int); char oob; int sockfd, clifd; void die(char *msg) { perror(msg); exit(-1); } int main(void) { struct sockaddr_in myaddr; char buf[BUFSIZ]; ssize_t nbytes; sigset_t sset, oset; sigemptyset(&sset); sigaddset(&sset, SIGURG); if (-1 == (sockfd = socket(AF_INET, SOCK_STREAM, 0))) die("socket()"); (void)memset(&myaddr, 0, sizeof(myaddr)); myaddr.sin_family = AF_INET; myaddr.sin_port = htons(PORT); myaddr.sin_addr.s_addr = htonl(INADDR_ANY); if (-1 == bind(sockfd, (struct sockaddr*)&myaddr, sizeof(myaddr))) die("bind()"); if (-1 == listen(sockfd, BACKLOG)) die("listen()"); if (-1 == fcntl(sockfd, F_SETOWN, getpid())) die("fcntl()"); if (SIG_ERR == signal(SIGURG, sigurg_handler)) die("signal()"); for (;;) { /* block SIGURG when accepting the connection */ // sigprocmask(SIG_SETMASK, &sset, &oset); printf("bloking in accept()\n"); if (-1 == (clifd = accept(sockfd, NULL, NULL))) die("accept()"); /* unblock SIGURG */ // sigprocmask(SIG_SETMASK, &oset, NULL); printf("recv()ing normal data\n"); nbytes = recv(clifd, buf, sizeof(buf), 0); buf[nbytes] = 0; /* null-terminate */ printf("%s", buf); } close(sockfd); } void sigurg_handler(int signo) { char buff[100]; ssize_t nbytes; printf("Signal %d SIGURG received\n",signo); if (clifd != 0) { if (-1 == (nbytes = recv(clifd, buff, sizeof(buff) - 1, MSG_OOB))) die("recv() in sigurg_handler()"); buff[nbytes] = 0; printf("from sigurg_handler: received \"%s\"\n", buff); } else { printf("clifd = %d\n", clifd); exit(1); } }