2月7日作业

news2024/11/15 23:31:25

分别通过select、多进程、多线程实现一个并发服务器

#include <myhd.h>
#define IP "192.168.250.100"
#define PORT 8888
int deal_cli_msg(int newfd,struct sockaddr_in cin)
{
	char buf[128] = "";
	while(1)
	{
		bzero(buf,sizeof(buf));
		int res = recv(newfd,buf,sizeof(buf),0);
		if(res == 0)
		{
			printf("客户端已下线\n");
			break;
		}
		else if(res < 0)
		{
			perror("recv error");
			return -1;
		}
		strcat(buf,"->is read\n");
		send(newfd,buf,sizeof(buf),0);
	}
	close(newfd);
	return 0;
}
void handler(int signo)
{
	if(signo == SIGCHLD)
	{
		while(waitpid(-1,NULL,WNOHANG) > 0);
	}
}
int main(int argc, const char *argv[])
{
	int sfd = socket(AF_INET,SOCK_STREAM,0);
	if(sfd == -1)
	{
		perror("socket error");
		return -1;
	}
	printf("socket success,sfd = %d\n",sfd);
	int reuse = 1;
	if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse)) == -1)
	{
		perror("setsocket error");
		return -1;
	}

	struct sockaddr_in sin;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(PORT);
	sin.sin_addr.s_addr = inet_addr(IP);

	if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin)) == -1)
	{
		perror("bind error");
		return -1;
	}
	printf("bind success");
	if(listen(sfd,128) == -1)
	{
		perror("listen error");
		return -1;
	}
	printf("listen success");
	struct sockaddr_in cin;
	cin.sin_family = AF_INET;
	socklen_t socklen = sizeof(cin);

	pid_t pid;

	if(signal(SIGCHLD,handler) == SIG_ERR)
	{
		perror("signal error");
		return -1;
	}

	while(1)
	{
		int newfd = accept(sfd,(struct sockaddr*)&cin,&socklen);
		if(newfd == -1)
		{
			perror("accept error");
			return -1;
		}
		printf("accept success");

		pid = fork();
		if(pid > 0)
		{
			close(newfd);
		}
		else if(pid == 0)
		{
			close(sfd);
			deal_cli_msg(newfd,cin);
			exit(EXIT_SUCCESS);
		}
		else
		{
			perror("fork error");
			return -1;
		}
	}
	close(sfd);
	return 0;
}

#include <myhd.h>
#define PORT 8888
#define IP "192.168.250.100"
struct msg_info
{
	int newfd;
	struct sockaddr_in cin;
};
void *deal_cli_msg(void *arg)
{
	int newfd = ((struct msg_info*)arg) -> newfd;
	struct sockaddr_in cin = ((struct msg_info*)arg) -> cin;
	char buf[128] = "";
	while(1)
	{
		bzero(buf,sizeof(buf));
		int res = recv(newfd,buf,sizeof(buf),0);
		if(res == 0)
		{
			printf("客户端已下线\n");
			break;
		}
		else if(res < 0)
		{
			perror("recv error");
			return NULL;
		}
		strcat(buf,"->is read\n");
		send(newfd,buf,sizeof(buf),0);
	}
	close(newfd);
	pthread_exit(NULL);
}
int main(int argc, const char *argv[])
{
	int sfd = socket(AF_INET,SOCK_STREAM,0);
	if(sfd == -1)
	{
		perror("socket error");
		return -1;
	}
	printf("socket success,sfd = %d\n",sfd);
	int reuse = 1;
	if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse)) == -1)
	{
		perror("setsockopt error");
		return -1;
	}
	printf("setsockopt success\n");
	struct sockaddr_in sin;
	sin.sin_family = AF_INET;
	sin.sin_port = htons(PORT);
	sin.sin_addr.s_addr = inet_addr(IP);
	if(bind(sfd,(struct sockaddr*)&sin,sizeof(sin)) == -1)
	{
		perror("bind error");
		return -1;
	}
	printf("bind success\n");
	if(listen(sfd,128) == -1)
	{
		perror("listen error");
		return -1;
	}
	printf("listen success\n");
	struct sockaddr_in cin;
	cin.sin_family = AF_INET;
	socklen_t socklen = sizeof(cin);
	while(1)
	{
		int newfd = accept(sfd,(struct sockaddr*)&cin,&socklen);
		if(newfd == -1)
		{
			perror("accept error");
			return -1;
		}
		printf("accept success\n");
		struct msg_info info = {newfd,cin};
		pthread_t tid;
		if(pthread_create(&tid,NULL,deal_cli_msg,&info) != 0)
		{
			printf("pthread_create error\n");
			return -1;
		}
		if(pthread_detach(tid) != 0)
		{
			printf("pthread_detach error\n");
			return -1;
		}

	}
	close(sfd);
	return 0;
}

#include<myhd.h>

#define PORT 8888              //端口号
#define IP "192.168.250.100"       //IP地址


//封装处理客户端信息函数
int deal_cli_msg(int newfd, struct sockaddr_in cin)
{
    //5、收发数据使用newfd完成通信
        char buf[128] = "";
        while(1)
        {
            //清空字符串
            bzero(buf, sizeof(buf));
            //read(newfd, buf, sizeof(buf));        //从套接字中读取客户端发来的消息
            int res = recv(newfd, buf, sizeof(buf), 0);        //从套接字中读取客户端发来的消息
            //buf[strlen(buf)-1] = '\0';

            //判断收到的结果
            if(res == 0)
            {
                printf("客户端已经下线\n");
                break;
            }else if(res < 0)
            {
                perror("recv error");
                return -1;
            }

            printf("[%s:%d]:%s\n", inet_ntoa(cin.sin_addr), ntohs(cin.sin_port), buf);

            //将读取的信息,加上一些字符发送回去
            strcat(buf, " -> is read\n");
            //    write(newfd, buf, sizeof(buf));
            send(newfd, buf, sizeof(buf), 0); 
        }

        close(newfd);             //关闭通信的套接字

}



int main(int argc, const char *argv[])
{
    //1、创建用于接受连接的套接字
    int sfd = socket(AF_INET, SOCK_STREAM, 0);
    if(sfd == -1)
    {
        perror("socket error");
        return -1;
    }

    printf("socket success sfd = %d\n", sfd);    //4


    //设置端口号快速重用
    int reuse = 1;
    if(setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1)
    {
        perror("setsockopt error");
        return -1;
    }
    printf("设置端口快速重用成功 _%d_ %s_ %s_\n", __LINE__, __FILE__, __func__);

    



    //2、绑定IP地址和端口号
    //2.1、填充要绑定的地址信息结构体
    struct sockaddr_in sin;
    sin.sin_family     = AF_INET;         //表明是ipv4
    sin.sin_port     = htons(PORT);        //端口号
    sin.sin_addr.s_addr = inet_addr(IP);     //IP地址

    //2.2、绑定
    if(bind(sfd, (struct sockaddr*)&sin, sizeof(sin))==-1)
    {
        perror("bind error");
        return -1;
    }
    printf("bind success _%d_ %s_ %s_\n", __LINE__, __FILE__, __func__);

    //3、将套接字设置成被动监听状态
    if(listen(sfd, 128) == -1)
    {
        perror("listen error");
        return -1;
    }

    printf("listen success _%d_ %s_ %s_\n", __LINE__, __FILE__, __func__);

    //4、阻塞等待客户端连接请求,如果有新的客户端连接,则创建一个新的用于通信的套接字
    //4.1、定义客户端地址信息结构体
    struct sockaddr_in cin;             //客户端地址信息结构体
    cin.sin_family     = AF_INET;
    socklen_t socklen = sizeof(cin);          //客户端地址信息的大小


    定义一个用于检测文件描述符的集合
    fd_set readfds, tempfds;                          //在栈区定义

    清空容器中的内容
    FD_ZERO(&readfds);
    将要检测的文件描述符放入集合中
    FD_SET(sfd, &readfds);           //将sfd文件描述符放入
    FD_SET(0, &readfds);             //将0号文件描述符放入



    //定义一个容器
    char buf[128] = "";
    int res = 0;             //接收select的返回值

    while(1)
    {
        将集合内容复制一份
        tempfds = readfds;

        使用select阻塞等待集合中的文件描述符有事件产生
        res = select(sfd+1, &tempfds, NULL, NULL, NULL);
        if(res == -1)
        {
            perror("select error");
            return -1;
        }else if(res == 0)
        {
            printf("time out\n");
            return -1;
        }


        判断sfd是否还在集合中
        if(FD_ISSET(sfd, &tempfds))
        {
            //4.2、阻塞接收客户端的链接请求,并且获取客户端的地址信息
            int newfd = accept(sfd, (struct sockaddr*)&cin, &socklen);
            if(newfd == -1)
            {
                perror("accept error");
                return -1;
            }
            printf("accept success _%d_ %s_ %s_\n", __LINE__, __FILE__, __func__);
	    deal_cli_msg(newfd,cin);

        }


        if(FD_ISSET(0, &tempfds))
        {
            //从终端获取数据
            fgets(buf, sizeof(buf), stdin);       //从终端获取数据
            buf[strlen(buf)-1]='\0';
            printf("触发终端输入事件:%s\n", buf);


        }


    }

    

    //6、关闭所有套接字
    close(sfd);               //关闭监听

    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1438787.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【已解决】onnx转换为rknn置信度大于1,图像出现乱框问题解决

前言 环境介绍&#xff1a; 1.编译环境 Ubuntu 18.04.5 LTS 2.RKNN版本 py3.8-rknn2-1.4.0 3.单板 迅为itop-3568开发板 一、现象 采用yolov5训练并将pt转换为onnx&#xff0c;再将onnx采用py3.8-rknn2-1.4.0推理转换为rknn出现置信度大于1&#xff0c;并且图像乱框问题…

(力扣)1314.矩阵区域和

给你一个 m x n 的矩阵 mat 和一个整数 k &#xff0c;请你返回一个矩阵 answer &#xff0c;其中每个 answer[i][j] 是所有满足下述条件的元素 mat[r][c] 的和&#xff1a; i - k < r < i k, j - k < c < j k 且(r, c) 在矩阵内。 示例 1&#xff1a; 输入&a…

春节假期如何高效管理Shopee虾皮本土店?技巧都给你整理好了!

EasyBoss ERP 对于中国人最重要的春节即将来临&#xff0c;但对于运营Shopee、TikTok Shop等平台的卖家而言&#xff0c;他们的客户可不会过春节。为了不影响店铺的业绩&#xff0c;很多卖家在春节期间都还是照常运营店铺&#xff0c;但又不想错过和家人团圆的机会怎么办&…

Redis.conf 配置文件解读

1、单位 容量单位不区分大小写&#xff0c;G和GB没有区别 配置文件 unit单位 对大小写不敏感 2、组合配置 可以使用 include 组合多个配置问题 3、网络配置 bind 127.0.0.1 # 绑定的ip protected-mode yes # 保护模式 port 6379 # 端口设置4、通用 GENERAL daemoniz…

STM32 硬件随机数发生器(RNG)

STM32 硬件随机数发生器 文章目录 STM32 硬件随机数发生器前言第1章 随机数发生器简介1.1 RNG主要特性1.2.RNG应用 第2章 RNG原理框图第3章 RNG相关寄存器3.1 RNG 控制寄存器 (RNG_CR)3.2 RNG 状态寄存器 (RNG_SR)3.3 RNG 数据寄存器 (RNG_DR) 第3章 RNG代码部分第4章 STM32F1 …

洛谷:P1219 [USACO1.5] 八皇后 Checker Challenge(dfs深度优先遍历求解)

题目描述 一个如下的 6666 的跳棋棋盘&#xff0c;有六个棋子被放置在棋盘上&#xff0c;使得每行、每列有且只有一个&#xff0c;每条对角线&#xff08;包括两条主对角线的所有平行线&#xff09;上至多有一个棋子。 上面的布局可以用序列 2 4 6 1 3 52 4 6 1 3 5 来描述&am…

wsl 安装minikube

Minikube是一种轻量化的Kubernetes集群&#xff0c;专为开发者和学习者设计&#xff0c;以便他们能够更好地学习和体验Kubernetes的功能。它利用个人PC的虚拟化环境&#xff0c;实现了Kubernetes的快速构建和启动。目前&#xff0c;Minikube已经支持在macOS、Linux和Windows平台…

浅析Linux内核模块自加载机制

文章目录 概述Linux内核模块管理内核模块存放目录modules系列文件 阻止模块启动时加载 systemd-module-load.service配置文件内核启动参数 udev动态加载机制udev工作流程udev配置示例&#xff1a;网卡重命名 相关参考 概述 模块自加载用于配置系统在启动时自动加载所需要的模块…

ctfshow-web11~20-WP

web11 根据提示,查询对ctfshow域名进行dns查询,查看TXT记录 阿里云查询链接:阿里云网站运维检测平台 获取flag成功 web12 根据题目提示,我们访问robots.txt,获取到后台地址 然后我们访问一下后台

算法效率的度量-时间空间复杂度

常对幂指阶 1.时间复杂度 事前预估 算法 时间开销 T(n) 与 问题规模 n 的关系&#xff08; T 表示 “ time ”&#xff09; 一般默认问题规模为n。 1.单循环 2.嵌套两层循环都为n 3.单层循环指数递增型 4.搜索型 链接 &#xff1a;第七章查找算法&#xff01;&#xff01…

C语言数组与扫雷游戏实现(详解)

扫雷游戏的功能说明 使⽤控制台实现经典的扫雷游戏游戏可以通过菜单实现继续玩或者退出游戏扫雷的棋盘是9*9的格子默认随机布置10个雷可以排查雷 ◦ 如果位置不是雷,就显示周围有几个雷 ◦ 如果位置是雷,就炸死游戏结束 ◦ 把除10个雷之外的所有雷都找出来,排雷成功,游戏结…

PMP备考的三个阶段及学习方法分享

PMP证书是项目管理必备的关键技能证书&#xff0c;是具备进行项目管理的重要技能体现。无论升职加薪&#xff0c;还是从事项目管理工作&#xff0c;都非常重要。 个人主要从事产品开发工作&#xff0c;开始逐渐承担一些项目经理角色&#xff0c;但目前项目管理知识薄弱&#x…

政安晨:示例演绎Python语言外部库的使用

这篇咱们示例演绎Python的一个重要能力&#xff1a;导入、运算符重载和进入外部库世界的生存技巧。 在咱们这一篇中&#xff0c;你将学习Python中的导入&#xff0c;获取使用不熟悉的库&#xff08;以及它们返回的对象&#xff09;的一些技巧&#xff0c;并深入了解运算符重载…

0206作业

TCP&#xff08;传输控制协议&#xff09;和 UDP&#xff08;用户数据报协议&#xff09;是两种常用的网络传输协议。它们之间的主要区别在于&#xff1a; 可靠性&#xff1a;TCP 是一种可靠的传输协议&#xff0c;它提供了数据传输的确认、重传和排序功能。如果数据在传输过程…

24.云原生ArgoCD高级之钩子

云原生专栏大纲 文章目录 Argo CD钩子如何定义钩子钩子删除策略 Argo CD钩子 Argo CD 是一个用于部署和管理 Kubernetes 应用程序的工具&#xff0c;它提供了一种声明式的方式来定义和自动化应用程序的部署过程。Argo CD 钩子&#xff08;Hooks&#xff09;是一种机制&#x…

Damn Small Linux 停更16年后,2024 回归更新

Damn Small Linux(DSL) 发行版释出了最新的 2024 版本&#xff0c;并重新定义了什么叫“Damn Small”。 DSL 诞生于 2005 年&#xff0c;原本是尝试提供一个 50MB 大小的 LiveCD&#xff0c;2008 年开发停滞。 2024 年原作者 John Andrews 宣布 DSL 复活&#xff0c;在几乎所…

springboot基础案例(二)

文章目录 前言一.需求分析: 分析这个项目含有哪些功能模块二.库表设计(概要设计): 1.分析系统有哪些表 2.分析表与表关系 3.确定表中字段(显性字段 隐性字段(业务字段))2.1 创建一个库: ems-thymeleaf2.2 创建 2张表三.编码(环境搭建)1.创建一个springboot项目 项目名字: ems-t…

【IDEA】反编译Jar包

反编译步骤 使用IDEA安装decompiler插件 找到decompiler插件文件夹所在位置&#xff08;IDEA安装路径/plugins/java-decompiler/lib &#xff09;&#xff0c;将需要反编译的jar包放到decompiler插件文件夹下&#xff0c;并创建一个空的文件夹&#xff0c;用来存放反编译后的…

Docker 有哪些常见的用途?

Docker 是一种容器化技术&#xff0c;它允许应用程序在不同的环境之间具有一致的运行环境。这使得 Docker 在开发和运维领域中非常受欢迎&#xff0c;因为它简化了应用程序的部署和管理。以下是 Docker 的一些常见用途&#xff1a; 快速部署应用程序 Docker 允许开发人员和运…

【TCP】高频面试题

前言 在IT行业的求职过程中&#xff0c;传输控制协议&#xff08;TCP&#xff09;作为网络通信的核心协议之一&#xff0c;其相关面试题常常出现在各大公司面试中。TCP的稳定性和可靠性是支撑互联网数据传输的基石&#xff0c;因此&#xff0c;对TCP有深入理解不仅能够帮助求职…