#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <errno.h> #include <signal.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <semaphore.h> #include <sys/wait.h> #include <sys/types.h>
#define MAX_MES 1024 #define MAX_CMD_STR 100 #define bprintf(fp, format, ...) \ if (fp == NULL) \ { \ printf(format, ##__VA_ARGS__); \ } \ else \ { \ printf(format, ##__VA_ARGS__); \ fprintf(fp, format, ##__VA_ARGS__); \ fflush(fp); \ }
#define COM_ADD struct sockaddr int echo_rqt(int sockfd); void sig_pipe(int signo); int sig_type = 0, sig_to_exit = 0;
int install_sig_handlers(); void sig_int(int signo);
int main(int argc, char const *argv[]) {
if (argc != 3) { printf("Usage:%s <IP> <PORT>\n", argv[0]); return -1; }
install_sig_handlers();
FILE *fd; fd = fopen("stu_srv_res_p.txt", "wb");
struct sockaddr_in srv_addr_v4, cli_addr; socklen_t cli_addr_len; cli_addr_len = sizeof(cli_addr); int port = atoi(argv[2]); inet_pton(AF_INET, argv[1], &srv_addr_v4.sin_addr); srv_addr_v4.sin_family = AF_INET; srv_addr_v4.sin_port = htons(port); bprintf(fd, "[srv] server[%s:%d] is initializing\n",argv[1], port);
int listenfd, confd; listenfd = socket(AF_INET, SOCK_STREAM, 0);
int res = bind(listenfd, (COM_ADD *)&srv_addr_v4, sizeof(srv_addr_v4)); if (res) { printf("[srv] bind failed\n"); }
res = listen(listenfd, 5); if (res) { printf("[srv] listen failed\n"); }
while (sig_to_exit != -1) { char h_addr[16] = {0}; int h_port;
confd = accept(listenfd, (COM_ADD *)&cli_addr, &cli_addr_len); if ( confd ==-1 && errno == EINTR) { if (sig_type == SIGINT) break; }
inet_ntop(AF_INET, &cli_addr.sin_addr, h_addr, sizeof(h_addr));
h_port = ntohs(cli_addr.sin_port); bprintf(fd, "[srv] client[%s:%d] is accepted\n", h_addr, h_port);
char child_log_filename[20]; memset(child_log_filename, 0, sizeof(child_log_filename));
sprintf(child_log_filename, "stu_srv_res_%d.txt", getpid()); fd = fopen(child_log_filename, "wb"); if (!fd) { printf("[srv] child exits, failed to open file \"stu_srv_res_%d.txt\"!\n", getpid()); exit(-1); } echo_rqt(confd);
close(confd); bprintf(fd, "[srv] connfd is closed\n"); fclose(fd); continue; }
close(listenfd); bprintf(fd, "[srv] listenfd is closed!\n"); bprintf(fd, "[srv] server is going to exiting!\n");
fclose(fd); return 0; }
int echo_rqt(int sock_confd) { int n_len; int h_len;
do { int res; res = read(sock_confd, &n_len, 4); if(res == 0) { return -1; }
h_len = ntohl(n_len); char *rcv_data = malloc(h_len); memset(rcv_data,0,sizeof(rcv_data)); do {
memset(rcv_data, 0, sizeof(rcv_data)); res = read(sock_confd, rcv_data, h_len);
while (res > 0 && res < h_len) { res += read(sock_confd, rcv_data + res, h_len - res); }
if (res < 0) { if (errno == EINTR) { if (sig_type == SIGINT) { return -1; } continue; } return -1; } if (!res) { return -1; }
break;
} while (1);
printf("[echo_rqt] %s\n", rcv_data);
write(sock_confd,&n_len,4); res = write(sock_confd, rcv_data, h_len);
free(rcv_data);
} while (1); }
void sig_pipe(int signo) { sig_type = signo; fprintf(stdout, "[srv] SIGPIPE is coming!\n"); }
void sig_child(int signo) { sig_type = signo; pid_t pid_child; fprintf(stdout, "[srv] SIGCHILD is coming!\n"); int stat; while ((pid_child = waitpid(-1, &stat, WNOHANG)) > 0) { printf("[srv](%d) child terminated\n", pid_child); }; } void sig_int(int signo) { sig_type = signo; sig_to_exit = -1; fprintf(stdout, "[srv] SIGINT is coming!\n"); }
int install_sig_handlers() { int res; struct sigaction sigact_pipe, old_sigact; sigact_pipe.sa_handler = sig_pipe; sigact_pipe.sa_flags = 0; sigact_pipe.sa_flags |= SA_RESTART; sigemptyset(&sigact_pipe.sa_mask); res = sigaction(SIGPIPE, &sigact_pipe, &old_sigact); if (res) { return -1; }
struct sigaction sigact_int; sigact_int.sa_flags = 0; sigact_int.sa_handler = sig_int; sigemptyset(&sigact_int.sa_mask); res = sigaction(SIGINT, &sigact_int, &old_sigact); if (res) { return -3; } return 0; }
|