多进程并发服务器实现
服务端实现
#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
#include <cerrno>
#include <netinet/in.h>
#include <csignal>
#include <arpa/inet.h>
#include <cstring>
using namespace std;
void sigchld_handler (int signum) {
int status;
pid_t pid;
// 循环等待回收所有子进程
while ((pid = waitpid(-1, &status, WNOHANG)) > 0) {
if (WIFEXITED(status)) {
cout << "Child process " << pid << " terminated normally with exit status: " << WEXITSTATUS(status) << endl;
} else {
cout << "Child process " << pid << " terminated abnormally" << endl;
}
}
}
int main (int argc, char *argv[]) {
// 注册处理函数
if (signal(SIGCHLD, sigchld_handler) == SIG_ERR) {
perror("Signal");
exit(-1);
}
// 创建监听Socket
int lfd = socket(AF_INET, SOCK_STREAM, 0);
if (-1 == lfd) {
perror("Create Socket:");
exit(-1);
}
// 绑定端口
sockaddr_in saddr;
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = htonl(INADDR_ANY);
saddr.sin_port = htons(9527);
if (-1 == bind(lfd, (sockaddr*)&saddr, sizeof(saddr))) {
perror("Bind Socket:");
exit(-1);
}
// 开始监听
if (-1 == listen(lfd, 1024)) {
perror("Listen:");
exit(-1);
}
for(;;) {
sockaddr_in caddr;
socklen_t caddr_size = sizeof(caddr);
int cfd = accept(lfd, (sockaddr*)&caddr, &caddr_size);
if (-1 == cfd) {
perror("Accept");
exit(-1);
}
char client_ip[1024];
if (nullptr == inet_ntop(AF_INET, &caddr.sin_addr.s_addr, client_ip, 1024)) {
perror("inet_ntop");
exit(-1);
}
int cpid = fork();
if (-1 == cpid) {
perror("Fork");
exit(-1);
} else if (0 == cpid) {
if (-1 == close(lfd) ) {
perror("Close lfd");
exit(-1);
}
char buffer[1024];
while (1) {
if (-1 == read(cfd, buffer, 1024)) {
perror("Read");
exit(-1);
}
cout << "Recived from " << client_ip << ":" << ntohs(caddr.sin_port) << " " << buffer << endl;
if (0 == strcmp(buffer, "exit")) {
break;
}
}
if (-1 == shutdown(cfd, SHUT_RDWR)) {
perror("Shutdown");
exit(-1);
}
if (-1 == close(cfd)) {
perror("Close cfd");
exit(-1);
}
return 0;
} else {
cout << "Client " << client_ip << ":" << ntohs(caddr.sin_port) << " accepted on process " << cpid << "!" << endl;
if (-1 == close(cfd)) {
perror("Close cfd");
exit(-1);
}
}
}
return 0;
}
客户端实现
#include <iostream>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <cerrno>
using namespace std;
int main(int argc, char *argv[]) {
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_port = htons(9527);
if(0 == inet_pton(AF_INET, "127.0.0.1", &(addr.sin_addr.s_addr))) {
cout << "Error IP" << endl;
exit(1);
}
int fd = socket(AF_INET, SOCK_STREAM, 0);
if (-1 == connect(fd, (sockaddr*)&addr, sizeof(addr))) {
perror("Connect Error!");
exit(1);
}
char buffer[1024];
for (;;) {
cin >> buffer;
write(fd, buffer, sizeof(buffer));
}
close(fd);
return 0;
}