C++回声服务器_5-多进程版本

news/2023/12/1 9:08:29

服务器和客户端都是用多进程来接收和发送数据。

服务器代码

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <unistd.h>
#include <csignal>
#include <sys/wait.h>
#include <arpa/inet.h>
#include <sys/socket.h>

const int BUF_SIZE = 30;

void error_handling(const char *messgae);
void read_childproc(int sig);

// 接收一个参数,argv[1]为端口号
int main(int argc, char *argcv[]) {
    int server_sock, client_sock;
    struct sockaddr_in server_addr, client_addr;

    pid_t pid;
    struct sigaction act;
    socklen_t addr_size;
    int str_len, state;
    char buf[BUF_SIZE];

    if (argc != 2) {
        printf("Usgae : %s <port>\n", argcv[0]);
        exit(1);
    }

    act.sa_handler = read_childproc;
    sigemptyset(&act.sa_mask);
    act.sa_flags = 0;
    state = sigaction(SIGCHLD, &act, 0);

    server_sock = socket(PF_INET, SOCK_STREAM, 0);
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    server_addr.sin_port = htons(atoi(argcv[1]));

    if (bind(server_sock, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) {
        error_handling("bind() error");
    }

    if (listen(server_sock, 5) == -1) {
        error_handling("listen() error");
    }

    while (1) {
        addr_size = sizeof(client_addr);
        client_sock =accept(server_sock, (struct sockaddr*)&server_addr, &addr_size);
        if (client_sock == -1) {
            continue;
        } else {
            puts("new client connected...");
        }

        pid = fork();
        if (pid == 0) {
            close(server_sock);
            while ((str_len = read(client_sock, buf, BUF_SIZE)) != 0) {
                write(client_sock, buf, str_len);
            }
            close(client_sock);
            puts("client disconnected...");
            return 0;
        } else {
            close(client_sock);
        }
    }

    close(server_sock);
    return 0;
}

客户端代码

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>

const int BUF_SIZE = 30;

void error_handling(const char *messgae);
void read_routine(int sock, char *buf);
void write_routine(int sock, char *buf);

// 接收两个参数,argv[1]为IP地址,argv[2]为端口号
int main(int argc, char *argv[]) {
    int sock;
    pid_t pid;
    char buf[BUF_SIZE];
    struct sockaddr_in server_addr;

    if (argc != 3) {
        printf("Usage : %s <IP> <port>\n", argv[0]);
        exit(1);
    }

    sock = socket(PF_INET, SOCK_STREAM, 0);
    memset(&server_addr, 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = inet_addr(argv[1]);
    server_addr.sin_port = htons(atoi(argv[2]));

    if (connect(sock, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) {
        error_handling("connect() error");
    }

    pid = fork();
    if (pid == 0) {
        write_routine(sock, buf);
    } else {
        read_routine(sock, buf);
    }
    close(sock);
    return 0;
}

辅助函数

#include <cstdio>
#include <cstdlib>
#include <csignal>
#include <cstring>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/socket.h>

const int BUF_SIZE = 30;

// 处理错误
void error_handling(const char *message) {
    printf("%s", message);
    exit(1);
}

// 读取进程退出状态
void read_childproc(int sig) {
    pid_t pid;
    int status;
    pid = waitpid(-1, &status, WNOHANG);
    printf("removed proc id: %d\n", pid);
}

// 客户端接收数据
void read_routine(int sock, char *buf) {
    while (1) {
        ssize_t str_len = read(sock, buf, BUF_SIZE);
        if (str_len == 0) {
            return;
        }
        buf[str_len] = 0;
        printf("Message from server: %s", buf);
    }
}

// 客户端发送数据
void write_routine(int sock, char *buf) {
    while (1) {
        fgets(buf, BUF_SIZE, stdin);
        if (!strcmp(buf, "q\n") || !strcmp(buf, "Q\n")) {
            shutdown(sock, SHUT_WR);
            return;
        }
        write(sock, buf, strlen(buf));
    }
}

项目代码

github

参考

《TCP/IP网络编程》


http://www.niftyadmin.cn/n/1934390.html

相关文章

苹果序列号查询知识汇总

手机评测网综合了苹果iPhone相关知识大全系列一&#xff1a;苹果序列号查询知识汇总。在这里&#xff0c;您可以找到有关Apple序列号查询的所有问题的答案。 &#xff08;如果编辑不小心错过了它&#xff0c;请不要射击我&#xff01;&#xff09;从本月开始&#xff0c;您将从…

ThinkSNS+的 SPA(H5)安装教程

H5 是 HTML 5 的缩写&#xff0c;也代表新浏览器技术和标准&#xff0c;例如一些先进浏览所支持的一些 HTML 5 标准 APIs 什么是 SPA 单页 Web 应用&#xff08;single page web application&#xff0c;SPA&#xff09;&#xff0c;就是只有一张 Web 页面的应用。单页应用程序…

mybatis+oracle如何批量执行多条update

接口 public void setStatus(List<Columns> columnsList); mapping xmlmapping 中使用foreach&#xff0c;关于标签的使用&#xff0c;资料非常多&#xff0c;在此不再赘述。例如&#xff1a; <update id"setStatus"><foreach collection"list&q…

牛慢跑

牛慢跑 据说是\(k\)短路模板&#xff0c;要用\(A^*\)&#xff0c;然而我不会。我是用拓扑排序加堆优化广搜水过去的。第一道完全靠自己做出来的紫题&#xff0c;调了两个小时&#xff0c;交了两遍。果然我还是太菜了。 正解的话&#xff0c;可以看红太阳的博客 题面 给出\(n\)个…

社工查询-最强社工查询网址汇总

社工查询网站 信用查询 1、信用中国 查询内容&#xff1a;工商注册企业和个人、行政许可和处罚 网址&#xff1a;http://www.creditchina.gov.cn/ 2、全国企业信用信息公示 查询内容&#xff1a;全国企业工商登记注册信息 http://gsxt.saic.gov.cn/&#xff08;导航&#xff0…

职业竞技选手金咕咕修理手机,天价换屏幕

尽管金咕咕是一名职业选手&#xff0c;但他一生中都很“扣”&#xff0c;在观看女主播的现场直播时他并没有给予太多礼物&#xff0c;因为他的钱在妻子的手中&#xff0c;甚至如果他想给它。女主播刷礼物时需要从妻子那里获得钱。这个过程有点困难。 最近&#xff0c;糖小幽发…

Sql 无法解决 equal to 运算中 Chinese_PRC_CI_AS 和 Chinese_PRC_90_CI_AI 之间的排序规则冲突...

导致问题原因为创建时&#xff0c;表所使用的排序规则不一致 解决办法&#xff1a; 在对比条件后增加 collate Chinese_PRC_90_CI_AI 的转义即可 如&#xff1a; where test1.FieldName test2.FieldName collate Chinese_PRC_90_CI_AI 转载于:https://www.cnblogs.com/catheri…

三星笔记本-星曜系列上手体验:简约时尚、轻薄便携

​自世界上第一台笔记本电脑诞生以来&#xff0c;整个行业一直在随着时代的变化而不断变化。为了迎合消费者的喜好&#xff0c;大型制造商努力工作并推出了次级笔记本电脑产品。例如&#xff0c;三星为我们带来了“轻薄便携时尚高品质”笔记本产品-三星笔记本星耀系列。 三星笔…

001.SSH配置文件

一 ssh配置文件路径 1.1 ssh客户端配置文件&#xff1a; 路径&#xff1a;/etc/ssh/ssh_config 1.2 ssh服务端配置文件&#xff1a; 路径&#xff1a;/etc/ssh/sshd_config 二 服务器端常用配置选项 2.1 常见配置项 1 Port 22 #端口2 3 ListenAddress #监听的IP4 5 Protocol 2 …

良心!苹果启动 MacBook Pro 电池更换计划

​在印象中&#xff0c;如果我没记错的话&#xff0c;这应该是Apple首次为MacBook Pro更换电池的程序 13英寸MacBook Pro&#xff08;无触摸条&#xff09;电池更换程序 苹果已经确定&#xff0c;少数13英寸MacBook Pro&#xff08;无触摸条&#xff09;计算机可能会因组件故…

HTML表单数据转JSON

问题描述 后端使用如下方式接收前端传入参数&#xff1a; 1 PostMapping(value "/test", produces MediaType.APPLICATION_JSON_UTF8_VALUE) 2ResponseBody 3 public Map<String, Object> test(RequestBody Map<String, Object> map) { 4 System.o…

华为MateX2屏幕曝光:外翻变内折 120Hz高刷新率

从过去一年的市场反馈来看&#xff0c;折叠屏幕手机非常受欢迎&#xff0c;特别是对于许多黄牛而言&#xff0c;只要抓住它就可以赚钱。 当然&#xff0c;对于普通消费者而言&#xff0c;折叠屏也可以带来创新的体验。在5G网络中使用它并不是太酷。对于华为来说&#xff0c;华…

.NetCore使用Swagger进行单版本或多版本控制处理

前面已经介绍过了Swagger的基础使用了 下面继续分别详细说明下 不添加版本控制以及添加版本控制的使用情况&#xff0c;其实也基本一致&#xff0c;对看起来可能更加容易理解 第一步 导入nuget包 nuget导入Swashbuckle.AspNetCore (对应有Swashbuckle.AspNetCore.Swagger、Swas…

iPhone SE Plus:处理器依旧采用A13芯片?

​苹果公司于今年4月正式发布了新的iPhone SE&#xff0c;这是因为A13仿生芯片的性能非常强大&#xff0c;并且它也是市场上为数不多的小屏幕手机之一。较低的价格使这款手机非常成功。市场销售业绩良好。 这款手机的推出还意味着苹果正在扩展其iPhone产品线&#xff0c;以满足…

苹果客服:iPhone 12又一重磅升级确认!

​根据手机评测网的最新消息&#xff0c;苹果制造合作伙伴Largan将从7月中旬开始为iPhone 12提供高端相机镜头&#xff08;交付&#xff09;。 与过去几年相比&#xff0c;Dali Optoelectronics的生产窗口&#xff08;在2020年下半年&#xff09;预计将延迟4到6周&#xff0c;这…

python之路-day12-迭代器闭包

一、昨日内容回顾 1、函数名 a、函数名是一个变量名 b、可以作为集合类的元素 c、可以作为参数进行传递 def func(fun): fn() d、可以作为返回值返回 def outer(): def inner(): xxx return 2、闭包 内层函数对外层函数的变量的访问 def outer(): a 10 def inner(): print(a) …
最新文章