Linux系统编程之多进程并发服务器简单实现

2023-05-16

服务端

#include<stdio.h>
#include<stdlib.h>
#include<signal.h>
#include<unistd.h>
#include<fcntl.h>
#include<string.h>
#include<sys/socket.h>
#include<arpa/inet.h>

#define PORT 8888
#define IP "127.0.0.1"

void catch_SIGCHLD(int signum){
    int waitret;
    while( (waitret = waitpid(-1,NULL,WNOHANG)) > 0);
    printf("cleaned %d\n",waitret);
    return;
}

int main(){
    //1、建立套接字
    int sfd = socket(AF_INET,SOCK_STREAM,0);
    if(sfd == -1){
        perror("socket error");
        exit(1);
    }
	//2、绑定
    struct sockaddr_in serv_addr;
    socklen_t serv_len;
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(PORT);
    inet_pton(AF_INET,IP,&serv_addr.sin_addr.s_addr);
    serv_len = sizeof(serv_addr);
    int ret = bind(sfd,(struct sockaddr*)&serv_addr,serv_len);
    if(ret == -1){
        perror("bind error");
        exit(2);
    }
	//3、监听
    ret = listen(sfd,128);
    if(ret == -1){
        perror("listen error");
        exit(3);
    }

    struct sockaddr_in clie_addr;
    int cfd;
    pid_t pid;
    while(1){
        //接受连接,连接到后就fork()子进程
        //父进程负责接受连接,子进程负责去读写
        socklen_t clie_len = sizeof(clie_addr);
        cfd = accept(sfd,(struct sockaddr*)&clie_addr,&clie_len);
        pid = fork();
        if(pid == -1){
            perror("fork error");
            exit(4);
        }else if(pid == 0){
            close(sfd);
            break;
        }else{
            close(cfd);
            //父进程中注册信号,写回调函数,让内核帮助回收子进程
            struct sigaction act;
            act.sa_handler = catch_SIGCHLD;
            sigemptyset(&act.sa_mask);
            act.sa_flags = 0;
            ret = sigaction(SIGCHLD,&act,NULL);
            if(ret == -1){
                perror("sigaction error");
                exit(5);
            }
        }
    }

    char buf[BUFSIZ];
    int len,i;
    while(1){
        len = read(cfd,buf,sizeof(buf));
        for(i = 0; i < len; i++){
            buf[i] = toupper(buf[i]);
        }
        write(cfd,buf,strlen(buf));
    }
    return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Linux系统编程之多进程并发服务器简单实现 的相关文章

  • MySQL基础

    本单元目标 一 为什么要学习数据库 二 数据库的相关概念 DBMS DB SQL 三 数据库存储数据的特点 四 初始MySQL MySQL产品的介绍 MySQL产品的安装 MySQL服务的启动和停止 MySQL服务的登录和退出 MySQL的
  • Thread类中的常用方法

    Thread类中的常用方法 xff08 学习总结 xff09 xff1a 序号函数作用1start 启动当前线程 xff1b 调用当前线程的run 2run 通常需要重写Thread类中的此方法 xff0c 将创建的线程要执行的操作生命在此
  • 线程的同步机制

    方式一 xff1a 同步代码块 span class token keyword synchronized span span class token punctuation span 同步监视器 span class token punc
  • Java常用类总结

    一 字符串相关的类 String类及其常用方法 1 String声明为final的 xff0c 不可被继承 2 String实现了Serializable接口 xff1a 表示字符串是支持序列化的 xff1b 实现了Comparable接口
  • java获取两个字符串中最大相同字串

    span class token keyword import span span class token keyword static span java span class token punctuation span lang sp
  • jdk提供的4种注解

    元注解 xff1a 对现有的注解进行解释说明的注解 Retention xff1a 指定所修饰的Annotation的生命周期 xff1a SOURCE CLASS xff08 默认行为 xff09 RUNTIME xff0c 只有声明为R
  • Java中List接口常用方法

    List除了从Collection集合继承的方法外 xff0c List集合里添加了一些根据索引来操作集合元素的方法 xff1a 序号返回值函数作用1voidadd int index Object ele 在index位置插入ele元素2
  • 对Java中Class类的理解并获取Class实例

    关于java lang Class类的理解 类的加载过程 xff1a 程序经过javac exe命令以后 xff0c 会生成一个或多个字节码文件 class结尾 接着我们使用java exe命令对某个字节码文件进行解释运行 相当于将某个字节
  • 类加载器ClassLoader及应用

    类加载器ClassLoader span class token keyword public span span class token keyword class span span class token class name Cla
  • 创建运行时类的对象、调用运行时类的指定结构以及获取运行时类的完整结构

    创建两个类 一个注解 一个接口 用来准备测试 span class token keyword public span span class token keyword class span span class token class n
  • Lambda表达式基本使用的六种情况

    举例 xff1a o1 o2 gt Integer compare o1 o2 格式 xff1a lambda操作符 或 箭头操作符 左边 xff1a lambda形参列表 xff08 其实就是接口中的抽象方法的形参列表 xff09 右边
  • DBeaver登录Mysql所犯的低级错误

    1 简介 DBeaver是免费和开源 xff08 GPL xff09 为开发人员和数据库管理员通用数据库工具 2 安装DBeaver 3 DBeave连接MySQL 3 1 在DBeaver界面的左上角 xff0c 找到加号 xff0c 选
  • sql基础

    DB xff1a 数据库 database xff1a 存储数据的 仓库 它保存了一系列有组织的数据 DBMS xff1a 数据库管理系统 Database Management System 数据库是通过DBMS创建和操作的容器 SQL
  • SQL之DQL语言

    1 基础查询 语法 xff1a select 查询列表 from 表名 其中 xff1a 表中的字段 常量值 表达式 函数 查询字段 xff1a select 字段 多个字段中间逗号隔开 from 表名 查询常量值 xff1a select
  • Ubuntu中安装.deb格式的软件包

    使用dpkg命令进行安装 dpkg命令常用格式如下 xff1a sudo dpkg I iptux deb 查看iptux deb软件包的详细信息 xff0c 包括软件名称 版本以及大小等 xff08 其中 I等价于 info xff09
  • SQL之DDL(数据定义语言)

    1 库的管理 创建库 create database if not exists 库名 更改库的字符集 alter database 库名 character set gbk utf 8 删除库 drop database if exist
  • SQL之事务级别

    事务 xff1a 一个或一组sql语句组成一个执行单元 xff0c 这个执行单元要么全部执行 xff0c 要么全部不执行 事务的ACID属性 xff1a 原子性 原子性是指事务是一个不可分割的工作单位 xff0c 事务中的操作要么都发生 x
  • 动态数组的创建、插入、按值删除、按位值删除、销毁(C语言实现)

    dynamic h文件 xff1a span class token macro property span class token directive keyword pragma span once span span class to
  • 统计字母字符串中字符出现的次数(C语言实现)

    span class token macro property span class token directive keyword define span CRT SECURE NO WARNINGS span span class to
  • C语言实现strlen()函数

    方式一 xff1a span class token macro property span class token directive keyword define span CRT SECURE NO WARNINGS span spa

随机推荐