【Linux网络编程】多进程并发服务器实现

随笔2小时前发布 华为时习知
2 0 0

多进程并发服务器实现

服务端实现

#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;
}
© 版权声明

相关文章

暂无评论

您必须登录才能参与评论!
立即登录
暂无评论...