/* Código concorrente de um servidor daytime escrevendo mensagens no * rsyslogd. Não é o código ideal (deveria tratar melhor os erros das * funções por exemplo) mas é suficiente para começar a entender como * se escreve servidores TCP usando sockets. * * RFC do daytime: http://www.faqs.org/rfcs/rfc867.html * * Prof. Daniel Batista em 30/11/2016. Baseado no código disponibilizado no livro do Stevens * * Bugs? Tente consertar primeiro! Depois me envie email :) batista@ime.usp.br */ #include #include #include #include #include #include #include #include #include #include #include #define MAXLINE 100 #define LISTENQ 1 void sig_chld(int signo) { pid_t pid; int status; while ( (pid = waitpid(-1, &status, WNOHANG)) > 0 ) syslog(LOG_INFO|LOG_USER,"Filho \%d terminou\n", pid); return; } int main(int argc, char **argv) { int listenfd, connfd; struct sockaddr_in servaddr; char buff[MAXLINE]; time_t ticks; pid_t pid; listenfd = socket(AF_INET, SOCK_STREAM, 0); if (listenfd < 0) { syslog(LOG_ERR|LOG_USER,"socket error %m :(\n"); exit(1); } bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(13); if (bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0 ) { syslog(LOG_ERR|LOG_USER,"bind error %m :(\n"); exit(2); } if (listen(listenfd, LISTENQ) < 0) { syslog(LOG_ERR|LOG_USER,"listen error %m :(\n"); exit(3); } if (signal(SIGCHLD, sig_chld) == SIG_ERR) { syslog(LOG_ERR|LOG_USER,"signal error %m :(\n"); exit(-1); } for ( ; ; ) { connfd = accept(listenfd, (struct sockaddr *) NULL, NULL); if ((pid = fork()) == 0) { close(listenfd); if (connfd < 0) syslog(LOG_ERR|LOG_USER,"accept error %m :(\n"); else { ticks = time(NULL); snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks)); if (write(connfd, buff, strlen(buff)) < 0) syslog(LOG_ERR|LOG_USER,"write error %m :(\n"); /* O sleep está aqui só para simular * uma conexão demorada */ sleep(10); close(connfd); exit(0); } } else close(connfd); } exit(0); }