代码
multi_process_server.c
#include "wrap.h"
#include <ctype.h>
#include <netinet/in.h>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#define SERV_PORT 6666
void catch_child(int signum)
{
while(waitpid(0, NULL, WNOHANG) > 0);
return;
}
int main(int argc, char *argv[])
{
int listen_fd, connect_fd;
int ret;
char buf[BUFSIZ], str[INET_ADDRSTRLEN];
pid_t pid;
struct sockaddr_in server_addr, client_addr;
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(SERV_PORT);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
listen_fd = Socket(AF_INET, SOCK_STREAM, 0);
Bind(listen_fd, (struct sockaddr *)&server_addr, sizeof(server_addr));
Listen(listen_fd, 128);
socklen_t client_addr_len = sizeof(client_addr);
printf("Accept connections ...\n");
while(1)
{
connect_fd = Accept(listen_fd, (struct sockaddr *)&client_addr, &client_addr_len);
printf("Connect fd: %d\n", connect_fd);
pid = fork();
if(pid < 0) perr_exit("fork error");
else if(pid == 0)
{
Close(listen_fd);
while(1)
{
ret = Read(connect_fd, buf, sizeof(buf));
if(ret == 0)
{
printf("the other side has been closed. \n");
Close(connect_fd);
break;
}
printf("Received from %s, port: %d\n",
inet_ntop(AF_INET, &client_addr.sin_addr, str, client_addr_len),
ntohs(client_addr.sin_port)
);
for(int i=0; i<ret; i++)
buf[i] = toupper(buf[i]);
Write(connect_fd, buf, ret);
Write(STDOUT_FILENO, buf, ret);
}
}
else
{
close(connect_fd);
struct sigaction act;
sigemptyset(&act.sa_mask);
act.sa_handler = catch_child;
act.sa_flags = 0;
ret = sigaction(SIGCHLD, &act, NULL);
if(ret == -1) perr_exit("sigaction error");
continue;
}
}
return 0;
}
wrap.h
#ifndef __WRAP_H_
#define __WRAP_H_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>
#include <pthread.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <ctype.h>
void perr_exit(const char *s);
int Accept(int fd, struct sockaddr *sa, socklen_t *salenptr);
int Bind(int fd, const struct sockaddr *sa, socklen_t salen);
int Connect(int fd, const struct sockaddr *sa, socklen_t salen);
int Listen(int fd, int backlog);
int Socket(int family, int type, int protocol);
ssize_t Read(int fd, void *ptr, size_t nbytes);
ssize_t Write(int fd, const void *ptr, size_t nbytes);
int Close(int fd);
ssize_t Readn(int fd, void *vptr, size_t n);
ssize_t Writen(int fd, const void *vptr, size_t n);
static ssize_t my_read(int fd, char *ptr);
ssize_t Readline(int fd, void *vptr, size_t maxlen);
#endif