重头开始嵌入式第三十二天(TCP多客户端模型)

1.多路IO

1.select

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <time.h>
/* According to POSIX.1-2001, POSIX.1-2008 */
#include <sys/select.h>/* According to earlier standards */
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
typedef struct sockaddr* (SA);
int main(int argc, char *argv[])
{//监听套接字int listfd = socket(AF_INET,SOCK_STREAM,0 );if(-1 ==listfd){perror("socket");exit(1);}struct sockaddr_in ser,cli;bzero(&ser,sizeof(ser));bzero(&cli,sizeof(cli));ser.sin_family = AF_INET;ser.sin_port = htons(50000);ser.sin_addr.s_addr =inet_addr("127.0.0.1");//man 7 socket int on = 1;setsockopt(listfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));setsockopt(listfd,SOL_SOCKET,SO_REUSEPORT,&on,sizeof(on));int ret = bind(listfd,(SA)&ser,sizeof(ser));if(-1 ==ret){perror("bind");exit(1);}//建立连接的排队数listen(listfd,3);socklen_t len = sizeof(cli);//1 create set fd_set rd_set,tmp_set;FD_ZERO(&rd_set);FD_ZERO(&tmp_set);//2.add fd  FD_SET(listfd,&tmp_set);int maxfd = listfd;while(1){   rd_set = tmp_set;select(maxfd+1,&rd_set,NULL,NULL,NULL);int i = 0 ;//通讯套接字for(i = 0 ;i<maxfd+1;i++){if(FD_ISSET(i,&rd_set) && i ==listfd){int conn = accept(listfd,(SA)&cli,&len);if(-1 == conn){perror("accept");// exit(1);continue;}FD_SET(conn,&tmp_set);if(conn>maxfd)maxfd = conn;}if(FD_ISSET(i,&rd_set) && i!=listfd){int conn = i ;char buf[512]={0};int rd_ret = recv(conn,buf,sizeof(buf),0);if(rd_ret<=0){FD_CLR(conn,&tmp_set);close(conn);printf("cli offline\n");break;}//printf("cli:%s\n",buf);time_t tm;time(&tm);sprintf(buf,"%s %s",buf,ctime(&tm));send(conn,buf,strlen(buf),0);}}}close(listfd);return 0;
}

2.epoll

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <time.h>#include <sys/epoll.h>
typedef struct sockaddr* (SA);
int add_fd(int epfd,int fd)
{struct epoll_event ev;ev.events = EPOLLIN;ev.data.fd = fd;int ret = epoll_ctl(epfd,EPOLL_CTL_ADD,fd,&ev);if(-1 == ret){perror("add fd");}return ret;
}
int del_fd(int epfd,int fd)
{struct epoll_event ev;ev.events = EPOLLIN;ev.data.fd = fd;int ret = epoll_ctl(epfd,EPOLL_CTL_DEL,fd,&ev);if(-1 == ret){perror("add fd");}return ret;
}int main(int argc, char *argv[])
{//监听套接字int listfd = socket(AF_INET,SOCK_STREAM,0 );if(-1 ==listfd){perror("socket");exit(1);}struct sockaddr_in ser,cli;bzero(&ser,sizeof(ser));bzero(&cli,sizeof(cli));ser.sin_family = AF_INET;ser.sin_port = htons(50000);ser.sin_addr.s_addr =inet_addr("127.0.0.1");//man 7 socket int on = 1;setsockopt(listfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));setsockopt(listfd,SOL_SOCKET,SO_REUSEPORT,&on,sizeof(on));int ret = bind(listfd,(SA)&ser,sizeof(ser));if(-1 ==ret){perror("bind");exit(1);}//建立连接的排队数listen(listfd,3);socklen_t len = sizeof(cli);struct epoll_event rev[10]={0};//1 create set int epfd = epoll_create(10);if(-1 == epfd){perror("epoll_create");return 1;}// 2 .add fd  add_fd(epfd,listfd);while(1){    //3 wait event int ep_ret = epoll_wait(epfd,rev,10,-1);int i = 0 ;//4 find fd handlefor(i = 0 ;i<ep_ret;i++){if(rev[i].data.fd == listfd){    //通讯套接字int conn = accept(listfd,(SA)&cli,&len);if(-1 == conn){perror("accept");continue;}add_fd(epfd,conn);}else {int conn = rev[i].data.fd;char buf[512]={0};int rd_ret = recv(conn,buf,sizeof(buf),0);if(rd_ret<=0){del_fd(epfd,conn);close(conn);break;}time_t tm;time(&tm);sprintf(buf,"%s %s",buf,ctime(&tm));send(conn,buf,strlen(buf),0);}}}close(listfd);return 0;
}

2.并发模型

1.进程

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <time.h>
#include <signal.h>
#include <sys/wait.h>
typedef struct sockaddr* (SA);
void handle(int num)
{wait(NULL);
}
int main(int argc, char *argv[])
{signal(SIGCHLD,handle);//监听套接字int listfd = socket(AF_INET,SOCK_STREAM,0 );if(-1 ==listfd){perror("socket");exit(1);}struct sockaddr_in ser,cli;bzero(&ser,sizeof(ser));bzero(&cli,sizeof(cli));ser.sin_family = AF_INET;ser.sin_port = htons(50000);ser.sin_addr.s_addr =inet_addr("127.0.0.1");//man 7 socket int on = 1;setsockopt(listfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));setsockopt(listfd,SOL_SOCKET,SO_REUSEPORT,&on,sizeof(on));int ret = bind(listfd,(SA)&ser,sizeof(ser));if(-1 ==ret){perror("bind");exit(1);}//建立连接的排队数listen(listfd,3);socklen_t len = sizeof(cli);while(1){//通讯套接字int conn = accept(listfd,(SA)&cli,&len);if(-1 == conn){perror("accept");//exit(1);continue;}pid_t pid = fork();if(0 == pid){close(listfd);while(1){char buf[512]={0};int rd_ret = recv(conn,buf,sizeof(buf),0);if(rd_ret<=0){printf("cli off line\n");close(conn);//break;exit(1);}printf("cli:%s\n",buf);time_t tm;time(&tm);sprintf(buf,"%s %s",buf,ctime(&tm));send(conn,buf,strlen(buf),0);}}else if (pid>0){close(conn);}else{printf("fork");continue;}}close(listfd);return 0;
}

2.线程

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <time.h>
#include <signal.h>
#include <sys/wait.h>
#include <pthread.h>
typedef struct sockaddr* (SA);void* th(void* arg)
{pthread_detach(pthread_self());int conn =* (int*)arg;//sem_post();while(1){char buf[512]={0};int rd_ret = recv(conn,buf,sizeof(buf),0);if(rd_ret<=0){printf("cli off line\n");close(conn);break;}printf("cli:%s\n",buf);time_t tm;time(&tm);sprintf(buf,"%s %s",buf,ctime(&tm));send(conn,buf,strlen(buf),0);}return NULL;
}
int main(int argc, char *argv[])
{//监听套接字int listfd = socket(AF_INET,SOCK_STREAM,0 );if(-1 ==listfd){perror("socket");exit(1);}struct sockaddr_in ser,cli;bzero(&ser,sizeof(ser));bzero(&cli,sizeof(cli));ser.sin_family = AF_INET;ser.sin_port = htons(50000);ser.sin_addr.s_addr =inet_addr("127.0.0.1");//man 7 socket int on = 1;setsockopt(listfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));setsockopt(listfd,SOL_SOCKET,SO_REUSEPORT,&on,sizeof(on));int ret = bind(listfd,(SA)&ser,sizeof(ser));if(-1 ==ret){perror("bind");exit(1);}//建立连接的排队数listen(listfd,3);socklen_t len = sizeof(cli);while(1){//通讯套接字int conn = accept(listfd,(SA)&cli,&len);if(-1 == conn){perror("accept");//exit(1);continue;}pthread_t tid;pthread_create(&tid,NULL,th,&conn);//sem_wait();// join();// 确保th中,把conn保存到局部变量中usleep(1000*5);}close(listfd);return 0;
}

3.循环

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h>#include <sys/socket.h>#include <netinet/in.h>#define PORT 8888#define BUFFER_SIZE 1024int main() {int server_fd, new_socket;struct sockaddr_in address;int addrlen = sizeof(address);char buffer[BUFFER_SIZE] = {0};// 创建服务器套接字if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {perror("socket failed");exit(EXIT_FAILURE);}address.sin_family = AF_INET;address.sin_addr.s_addr = INADDR_ANY;address.sin_port = htons(PORT);// 绑定套接字到指定端口if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {perror("bind failed");exit(EXIT_FAILURE);}// 监听连接if (listen(server_fd, 3) < 0) {perror("listen failed");exit(EXIT_FAILURE);}while (1) {// 接受新的连接if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {perror("accept failed");exit(EXIT_FAILURE);}while (1) {int valread = read(new_socket, buffer, BUFFER_SIZE);if (valread <= 0) {break;}printf("Received from client: %s\n", buffer);send(new_socket, buffer, strlen(buffer), 0);memset(buffer, 0, BUFFER_SIZE);}close(new_socket);}return 0;}

 

 

 

 

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

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

相关文章

基于人体关节夹角的人体动作识别算法(代码+数据集)

为此本文提出了一个基于人体关节夹角的人体动作识别算法&#xff0c;主要做了以下工作&#xff1a; &#xff08;1&#xff09;提出了一个可解释性强&#xff0c;耗费算力较少且鲁棒性较高的基于人体关节夹角的人体动作序列的特征抽取方法。 &#xff08;2&#xff09;本文所使…

PCL 移动立方体三维重建——RBF算法【2024最新版】

目录 一、算法原理1、算法概述2、参考文献二、代码实现三、结果展示四、相关链接本文由CSDN点云侠原创,原文链接,首发于:2024年9月1日。如果你不是在点云侠的博客中看到该文章,那么此处便是不要脸的爬虫与GPT。 一、算法原理 1、算法概述 该算法实现的是Reconstruction a…

单片机配置导入导出功能设计(一种思路)

背景&#xff1a; 为了方便部分不开放到屏幕的配置进行修改&#xff0c;兼容离线机器&#xff0c;也支持产线大批量配置导入&#xff0c;提高生产效率&#xff0c;特此研发配置导入导出功能。 原理&#xff1a; 上电监测到U盘和文件系统正常后&#xff0c;监测是否存在配置文件…

贸易术语你都不懂,你还做什么外贸

外贸小伙伴们&#xff0c;连贸易术语都不懂&#xff0c;还做啥外贸&#xff1f;别担心&#xff0c;今天我给大家整理了常见的外贸贸易术语&#xff0c;让你轻松入门&#xff0c;快速上手&#xff01; 1、FOB: Free On Board 船上交货价。按离岸价进行的交易&#xff0c;买方…

Java并发线程 共享模型之管程 5

1. 生产者消费者 package cn.itcast.testcopy;import cn.itcast.n2copy.util.Sleeper; import lombok.extern.slf4j.Slf4j;import java.util.LinkedList;/*** ClassName: Test21* Package: cn.itcast.testcopy* Description: 生产者消费者** Author: 1043* Create: 2024/9/4 - …

软件测试之压力测试知识总结

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 压力测试 压力测试是一种软件测试&#xff0c;用于验证软件应用程序的稳定性和可靠性。压力测试的目标是在极其沉重的负载条件下测量软件的健壮性和错误处理能力&…

Vue 3 的性能提升具体体现在哪些方面?

Vue 3 的性能提升体现在多个方面&#xff0c;以下是一些具体的例子&#xff1a; 基于 Proxy 的响应式系统&#xff1a; Vue 2 使用 Object.defineProperty 来实现响应式数据绑定&#xff0c;这种方式在处理数组或添加新的属性时存在局限性。Vue 3 引入了基于 Proxy 的响应式系统…

Android 获取通话记录

在某些App的开发者&#xff0c;获取通话记录有时候是必要的&#xff08;现在都要申请相对于权限哦&#xff0c;App上架得说明为啥获取此权限&#xff09;。 因为工作风控数据收集经常会用到&#xff0c;在此做个总结。 大致步骤 1.权限声明 2.申请权限 3.获取通话记录 4.…

LNMP环境搭建(Linux+nginx+Mysql+PHP)超详细攻略

目录 一.LNMP简介 1.1LNMP架构的特点 二.详细安装步骤 2.1MySQL安装 2.1-1Yum安装 2.1-2 编译安装 2.1-3二进制安装 2.1-4 RPM安装 2.2Nginx安装 2.2-1编译安装nginx 2.2-2yum安装nginx 2.3验证Nginx安装 2.4PHP安装 2.4-1编译安装PHP 2.4-2yum安装PHP 2.5 Nginx 配…

PMP–一、二、三模、冲刺、必刷–分类–14.敏捷–技巧--累积流图

文章目录 技巧一模二模三模14.敏捷–敏捷团队的衡量结果–累积流图&#xff1a;1、 敏捷项目的项目经理担心团队在最近的迭代中失去了动力。项目经理应该使用哪两种工具来分析团队绩效&#xff1f;&#xff08;选择两个&#xff09; 冲刺必刷7.成本管理--挣值分析燃尽图仅能了解…

Android --- observer和observerForever的区别

observe 和 observeForever 是 LiveData 中的两个方法&#xff0c;用于观察数据的变化&#xff0c;但它们在生命周期管理和适用场景上有区别&#xff1a; ---->observe: 用途: 注册一个观察者&#xff0c;该观察者在 LifecycleOwner&#xff08;如 Activity 或 Fragment&am…

From Man vs Machine to Man + Machine

From Man vs. Machine to Man Machine: The Art and AI of Stock Analyses 论文阅读 文章目录 From Man vs. Machine to Man Machine: The Art and AI of Stock Analyses 论文阅读 AbstractConstruction and Performance of the AI AnalystMethodologyThe Performance of Ana…

一款用于分析java socket连接问题的工具

network-tools 介绍 network-tools基于sun jdk、Oracle jdk开发&#xff0c;拦截基于java socket请求&#xff0c;它包括 ​ http 客户端 ​ jdbc 客户端 ​ mq 客户端 ​ redis 客户端 目前提供如下功能&#xff1a; ​ 最近端点连接情况 ​ 最近与远程端点连接情况&am…

【Windows】【C++】【Udp】 udp通信协议详解和示例

在 Windows 平台上&#xff0c;使用 C 实现的 UDP 通信服务器和客户端示例代码稍有不同&#xff0c;因为 Windows 使用 Winsock API 进行网络编程。下面是一个简单的 UDP 服务器和客户端的实现示例&#xff0c;包括详细的代码和说明。 UDP 服务器代码示例&#xff08;Windows&…

Mybatis分页查询主从表

先主查询&#xff0c;再关联子查询&#xff0c;不影响分页效果&#xff0c;否则子查询也会参与分页。 <resultMap id"Hdr" type"com.Hdr"><id column"crh_id" property"id" javaType"int"/><collection prop…

计算机网络 第1章 概述

文章目录 计算机网络概念计算机网络的组成计算机网络的功能三种数据交换技术电路交换&#xff08;Circuit Switching&#xff09;报文交换&#xff08;message&#xff09;分组交换 三种交换方式性能对比计算机网络的分类计算机网络的性能指标性能指标1&#xff1a;速率性能指标…

【优化】Nginx 配置页面请求不走缓存 浏览器页面禁用缓存

【优化】Nginx 配置页面请求不走缓存 禁用缓存 目录 【优化】Nginx 配置页面请求不走缓存 禁用缓存 对所有请求禁用缓存 对特定location禁用缓存 注意事项 全局禁用缓存 要配置Nginx使其不缓存内容&#xff0c;通常是指禁止浏览器缓存响应的内容&#xff0c;或者是在代理…

单片机-串口通信(二)

目录 一、串口概念 1.相关概念&#xff1a; 按数据传输方式分类&#xff1a; 按时钟分类 二、STM32F103ZET6中串口 USART特性&#xff1a; NRZ数据格式&#xff1a; 三、配置串口通信 查看硬件原理图 软件配置流程 USART相关的寄存器 新建my_usart1.c和my_usart1.h …

将Google Chrome或Microsoft Edge浏览器的地址栏隐藏的方法

将Google Chrome或Microsoft Edge浏览器的地址栏隐藏的方法 目标效果示范 我们以百度首页为例&#xff0c;普通模式启动的页面通常会显示地址栏&#xff0c;如下图所示&#xff1a; 而本文要实现的效果是隐去地址栏和书签栏&#xff08;如果有的话&#xff09;&#xff0c;无…