#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, FILE *fd,char * old_file_name); 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"); fprintf(stdout, "[srv](%d) stu_srv_res_p.txt is opened!\n", getpid());
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](%d) server[%s:%d] is initializing\n",getpid(),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)); printf("bind erro = %d\n%s\n",errno,strerror(errno)); printf("bind_res = %d\n",res); if (res) { printf("[srv](%d)bind failed\n", getpid()); }
res = listen(listenfd, 5); printf("listen_res = %d\n",res); if (res) { printf("[srv](%d)listen failed\n", getpid()); }
while (sig_to_exit != -1) { char h_addr[16] = {0}; int h_port; printf("before accept\n"); confd = accept(listenfd, (COM_ADD *)&cli_addr,&cli_addr_len); printf("confd = %d,errono = %d \n",confd,errno);
if (confd == -1 && errno == EINTR) { printf("into sig int\n"); 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); printf("port is = %d\n",h_port); bprintf(fd, "[srv](%d) client[%s:%d] is accepted\n", getpid(), h_addr, h_port);
pid_t pd; pd = fork(); if (pd < 0) { printf("fork error num:%d\n,error is :%s\n", errno, strerror(errno)); }
else if (pd == 0) {
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](%d) child exits, failed to open file \"stu_srv_res_%d.txt\"!\n",getpid(),getpid()); exit(-1); }
fprintf(stdout, "[srv](%d) stu_srv_res_%d.txt is opened!\n",getpid(),getpid()); bprintf(fd, "[srv](%d) child process is created!\n",getpid());
close(listenfd); bprintf(fd,"[srv](%d) listenfd is closed\n",getpid());
int pin; pin = echo_rqt(confd, fd,child_log_filename); if( pin == -1 ) { close(confd); bprintf(fd,"[srv](%d) connfd is closed\n",getpid()); bprintf(fd,"[srv](%d) child process is goning to exit!\n",getpid()) fclose(fd); fprintf(stdout, "[srv](%d) stu_srv_res_%d is closed\n",getpid(),getpid()); bprintf(fd, "[srv](%d) child exits, client PIN returned by echo_rqt() error!\n", getpid()); exit(-1); } } else { close(confd); } }
close(listenfd); bprintf(fd, "[srv](%d) listenfd is closed!\n", getpid()); bprintf(fd, "[srv](%d) parent process is going to exit!\n",getpid());
fclose(fd); fprintf(stdout, "[srv](%d) stu_srv_res_p is closed\n",getpid()); printf("....\n"); return 0; }
int echo_rqt(int sock_confd, FILE *fd,char *old_file_name) { int n_pin; int h_pin; int n_len; int h_len;
char send_data[MAX_CMD_STR + 1 + 8] = {0}; char rcv_data[MAX_CMD_STR + 1 + 8] = {0};
do { do { int res = read(sock_confd,&n_pin,4);
printf("res_pin = %d\n",res); printf("n_pin =%d\n",n_pin); if (res < 0) { bprintf(fd, "[srv](%d) read pin_n return %d and errno is %d!\n",getpid(),res,errno); if (errno == EINTR) { if (sig_type == SIGINT) return -1; continue; } return -1; } if (!res) { char new_child_log_filename[20];
memset(new_child_log_filename, 0, sizeof(new_child_log_filename)); sprintf(new_child_log_filename, "stu_srv_res_%d.txt", h_pin);
if (!rename(old_file_name, new_child_log_filename)) { bprintf(fd, "[srv](%d) res file rename done!\n",getpid()); }
else { bprintf(fd, "[srv](%d) child exits, res file rename failed!\n",getpid()); }
return -1; }
h_pin = ntohl(n_pin); printf("h_pin=%d\n",h_pin); break; } while (1);
do { int res = read(sock_confd,&n_len,4); printf("res_len = %d\n",res); if (res < 0) { bprintf(fd, "[srv](%d) read len_n return %d and errno is %d\n",getpid(),res,errno); if (errno == EINTR) { if (sig_type == SIGINT) return -1; continue; } return -1; } if (!res) { return -1; } h_len = ntohl(n_len); printf("h_len = %d\n",h_len); break; } while (1);
do { memset(rcv_data,0,sizeof(rcv_data)); int res = read(sock_confd, rcv_data, h_len); printf("res_str = %d\n",res);
printf("[srv](%d)str erro is %d:%s\n",getpid(),errno,strerror(errno)); while (res < h_len) { printf("res = %d\n",res); res += read(sock_confd, rcv_data + res, h_len-res); } if (res < 0) { bprintf(fd, "[srv](%d) read data return %d and errno is %d,\n", getpid(), res, errno); if (errno == EINTR) { if (sig_type == SIGINT) { return -1; } continue; } return -1; } if (!res) { return -1; }
break;
} while (1);
bprintf(fd,"[echo_rqt](%d) %s\n",getpid(),rcv_data); memset(send_data + 8,0,sizeof(send_data) - 8); memcpy(send_data + 8,rcv_data,h_len); memcpy(send_data, &n_pin,4); memcpy(send_data + 4, &n_len,4);
int res = write(sock_confd,send_data,h_len + 8); memset(rcv_data,0,sizeof(rcv_data));
printf("send data is = %s\n",send_data + 8); printf("...\n"); } while (1); }
void sig_pipe(int signo) { sig_type = signo; fprintf(stdout, "[srv](%d) SIGPIPE is coming!\n",getpid()); }
void sig_child(int signo) { sig_type = signo; pid_t pid_child; fprintf(stdout, "[srv](%d) SIGCHILD is coming!\n",getpid()); 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](%d) SIGINT is coming!\n",getpid()); }
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_child; sigact_child.sa_handler = sig_child; sigact_child.sa_flags = 0; sigact_child.sa_flags |= SA_RESTART; sigemptyset(&sigact_child.sa_mask); res = sigaction(SIGCHLD, &sigact_child, &old_sigact); if (res) { return -2; } 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; }
|