网络计算机模拟实现

今天给大家说说前几天完成的一个模拟的网络计算机吧,虽然计算机的模拟实现的原理很简单,但是如果要想写乘网络的,个人认为是不简单的。基本上算是包涵了套接字编程的三分之一的知识点,此处的套接字编程指的是在理解TCP/IP五层协议的基础上,如果不算理解这些协议的话,那么我感觉实现这个,应该是包含了多半的套接字编程。下面就让我们看看代码吧!

#pragma once
#include <pthread.h>
#include <iostream>
#include <queue>
#include <string>
#include <semaphore.h>
#include "deal.hpp"
#define PTHREAD_NUM 6
#define TASKNUM 5template <class T>
class pthreadPool;
template <class T>
struct data
{std::string _name;pthreadPool<T> *_str;data(pthreadPool<T> *str) : _str(str){}
};
template <class T>
class pthreadPool
{
public:friend data<T>;static pthreadPool<T> *get(){return _str;}void run(const T &x, int sock){_task = x;_sock = sock;}void start(){for (size_t i = 0; i < PTHREAD_NUM; i++){data<T> *p = new data<T>(this);if (i % 2 == 0)p->_name = "product";elsep->_name = "consumer";pthread_create(tid + i, nullptr, enter, p);}std::cout << "wancheng" << std::endl;}~pthreadPool(){pthread_mutex_destroy(&_pmtx);pthread_mutex_destroy(&_cmtx);sem_destroy(&_p);sem_destroy(&_c);for (size_t i = 0; i < PTHREAD_NUM; i++)pthread_join(tid[i], nullptr);}private:int _sock = 0;T _task = T();pthread_t tid[PTHREAD_NUM];pthread_mutex_t _pmtx;pthread_mutex_t _cmtx;sem_t _p;sem_t _c;int _pp = 0;int _cc = 0;std::vector<T> _v;static pthreadPool<T> *_str;pthreadPool(){_v.resize(TASKNUM);sem_init(&_p, 0, TASKNUM);sem_init(&_c, 0, 0);pthread_mutex_init(&_cmtx, nullptr);pthread_mutex_init(&_pmtx, nullptr);}void product(const T x){// 生产数据sem_wait(&_p);pthread_mutex_lock(&_pmtx);_v[_pp++] = x;_pp = _pp % TASKNUM;_task = T();pthread_mutex_unlock(&_pmtx);sem_post(&_c);}void consumer(){T x;// 消费数据sem_wait(&_c);pthread_mutex_lock(&_cmtx);x = _v[_cc++];_cc = _cc % TASKNUM;pthread_mutex_unlock(&_cmtx);sem_post(&_p);// 处理数据deal(x, _sock);}static void *enter(void *args){data<T> *p = reinterpret_cast<data<T> *>(args);while (true){if (strcmp(p->_name.c_str(), "product") == 0 && p->_str->_task != T())p->_str->product(p->_str->_task);else if (strcmp(p->_name.c_str(), "consumer") == 0)p->_str->consumer();//std::cout << "xiuxi" << std::endl;continue;}delete p;return nullptr;}
};
template <class T>
pthreadPool<T> *pthreadPool<T>::_str = new pthreadPool<T>();
#pragma once
#include <iostream>
#include <string>
#include <cstring>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
void deal(std::string &data, int sock)
{// 反序列化std::string respon;int x = 0;int y = 0;char op = '\0';int lpos = data.find(" ");int rpos = data.rfind(" ");// std::cout<<lpos<<" "<<rpos<<std::endl;if (lpos != std::string::npos && rpos != std::string::npos){x = atoi(data.substr(lpos - 1).c_str());op = *data.substr(lpos + 1, rpos - 1).c_str();y = atoi(data.substr(rpos + 1).c_str());// std::cout<<x<<" "<<y<<" "<<op<<std::endl;}else{if (data == std::string())return;else{std::cout << "式子格式错误" << std::endl;exit(4);}}// 处理switch (op){case '+':respon = std::to_string(x + y);break;case '-':respon = std::to_string(x - y);break;case '*':respon = std::to_string(x * y);break;case '/':respon = std::to_string(x / y);break;default:std::cout << "计算格式错误" << std::endl;break;}// 关闭链接send(sock, respon.c_str(), respon.size(), 0);close(sock);
}
#include <iostream>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <signal.h>
#include <pthread.h>
#include <arpa/inet.h>
#include <cstring>
#include <string>
#include "pthreadPool.hpp"
#define NUMSIZE 1024
const int listen_queue_flag = 20;
void func(pthreadPool<std::string> &pt, int sock)
{char buffer[NUMSIZE];memset(buffer, 0, NUMSIZE);ssize_t s = recv(sock, buffer, NUMSIZE, 0);std::cout << buffer << std::endl;if (s > 0){std::string bufe = buffer;pt.run(bufe, sock);}
}
// 主函数
int main(int argc, char *argv[])
{signal(SIGPIPE, SIG_IGN);signal(SIGCHLD, SIG_IGN);if (argc != 2){std::cout << "格式错误" << std::endl;exit(1);}// 创建套接字int listensock = socket(AF_INET, SOCK_STREAM, 0);if (listensock < 0){std::cout << "socket enrro" << std::endl;exit(1);}// 开始绑定sockaddr_in local;local.sin_addr.s_addr = inet_addr("0.0.0.0");local.sin_family = AF_INET;local.sin_port = htons(atoi(argv[1]));int ret = bind(listensock, (sockaddr *)&local, sizeof(local));if (ret < 0){std::cout << "bind enrro" << std::endl;exit(2);}// 监听int listens = listen(listensock, listen_queue_flag);if (listens < 0){std::cout << "listen enrro" << std::endl;exit(3);}// 建立线程池pthreadPool<std::string> *pstr = pthreadPool<std::string>::get();pstr->start();// 建立链接while (true){sockaddr_in client;socklen_t len = sizeof(client);int sersock = accept(listensock, (sockaddr *)&client, &len);if (sersock < 0){std::cout << "accept enrro" << std::endl;continue;}func(*pstr, sersock);}return 0;
}
#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <cstring>
#include <unistd.h>
#define NUM 10
int main(int argc, char *argv[])
{if (argc != 3){std::cout << "格式错误" << std::endl;exit(1);}int sock = socket(AF_INET, SOCK_STREAM, 0);if (sock < 0){std::cout << "socket enrro" << std::endl;exit(2);}sockaddr_in serve;memset(&serve, 0, sizeof(serve));serve.sin_addr.s_addr = inet_addr(argv[1]);serve.sin_family = AF_INET;serve.sin_port = htons(atoi(argv[2]));int ret = connect(sock, (sockaddr *)&serve, sizeof(serve));// std::cout<<ret<<std::endl;if (ret >= 0){// 连接成功std::string buffer;getline(std::cin, buffer);// std::cout<<buffer<<std::endl;send(sock, buffer.c_str(), buffer.size(), 0);char bufe[NUM];memset(bufe, 0, NUM);ssize_t s = recv(sock, bufe, NUM, 0);std::cout << bufe << std::endl;close(sock);}else{std::cout<<"连接错误"<<std::endl;exit(5);}return 0;
}

以上就是代码,代码量不大,但是主要是考虑的比较多。我又加了个线程池。如果是单生产者还好,但是我写成了多生产者和多消费者,这里就有好多问题,困扰了我很久,这个计算机我大概写了有半个月左右吧,难就难在了这个线程池的地方。下面先说说他的问题吧。

1.

首先就是我在服务端创建线程池的时候,迷糊了很久,刚开始我是在服务端创建了一个新线程,让这个新线程去调用线程池的函数,但是后来我发现不行,因为当时我是把关闭套接字的文件写到了服务端,这就导致一个问题,线程创建完成之后,线程池中的线程回去执行任务,但是,服务端的线程出来之后,就直接关闭文件了,导致无法发送。所以我就想了很长时间,最后把这个操作写到了处理函数的那里,这样就避免了连接错误以及服务端创建线程的问题,减少了消耗。

2.

其次而来的问题就是,因为这个线程池是多生产者多消费者的,所以我就想的是提高一点效率,携程了可以并发执行的模型,但是问题又来了,他们怎么插入任务,要知道的是服务端可不是生产者的角色,他只是负责把读取的人插到线程池,这就引发了一个问题,怎么插,所以我想了想,便在县城的私有成员变量中,写了一个任务和套接字的文件描述符。但是这样还有问题,不知道大家注意到了我的线程池中的插入,我没有用引用,这样会造成拷贝构造,但是这样可以大大降低错误发生概率,是的,解决不了(我没有想到解决方法),这样写的目的是,在一个客户端访问时,我先运行run函数,然后我的生产者会插入任务,但是如果刚好在插入任务的之前,又有一个客户端访问时,此时的线程中的任务变量就会改变。所以我没有用引用,这样的话就可以在一定概率上解决这个问题,但是还是彻底解决不了。

3.

其次就是我写的是短连接,这个可以保证多人同时访问服务端不崩。

如果上面的实现用单生产者,多消费者的话,就可以解决,此方法如果用小伙伴知道解决的方法,希望告知,谢谢。

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

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

相关文章

泡沫玻璃市场分析:预计2028年将达到14亿美元

泡沫玻璃最早是由美国匹兹堡康宁公司发明的&#xff0c;是由碎玻璃、发泡剂、改性添加剂和发泡促进剂等&#xff0c;经过细粉碎和均匀混合后&#xff0c;再经过高温熔化&#xff0c;发泡、退火而制成的无机非金属玻璃材料。它是由大量直径为1~2毫米的均匀气泡结构组成。其中吸声…

Linux 常用命令----mktemp 命令

文章目录 基本用法实例演示高级用法注意事项 mktemp 命令用于创建一个临时文件或目录&#xff0c;这在需要处理临时数据或进行安全性测试时非常有用。使用 mktemp 可以保证文件名的唯一性&#xff0c;避免因文件名冲突而导致的问题。 基本用法 创建临时文件: 命令 mktemp 默认…

Go语言基础知识学习(一)

Go基本数据类型 bool bool型值可以为true或者false,例子&#xff1a; var b bool true数值型 类型表示范围int8有符号8位整型-128 ~ 127int16有符号16位整型-32768 ~ 32767int32有符号32位整型-2147783648 ~ 2147483647int64有符号64位整型uint8无符号8位整型0 ~ 255uint16…

优思学院|如何建立公司运营指标体系?如何推行六西格玛改进运营指标?

关键绩效指标 (KPI) 是测量您团队或组织朝重要商业目标进展表现如何的量化指标&#xff0c;组织会在多个层面使用 KPI&#xff0c;这视乎您想要追踪何指标而定&#xff0c;您可以设定全组织的、特定团队的、或甚至是个人 KPI。 良好的KPI能让公司管理者掌握组织的营运是否进度…

使用React 18、Echarts和MUI实现温度计

关键词 React 18 Echarts和MUI 前言 在本文中&#xff0c;我们将结合使用React 18、Echarts和MUI&#xff08;Material-UI&#xff09;库&#xff0c;展示如何实现一个交互性的温度计。我们将使用Echarts绘制温度计的外观&#xff0c;并使用MUI创建一个漂亮的用户界面。 本文…

点评项目——分布式锁

2023.12.10 集群模式下的并发安全问题及解决 随着现在分布式系统越来越普及&#xff0c;一个应用往往会部署在多台机器上&#xff08;多节点&#xff09;&#xff0c;通过加锁可以解决在单机情况下的一人一单安全问题&#xff0c;但是在集群模式下就不行了。见下图&#xff1a…

在 Android WebView 中实现和 JavaScript 的互操作

前言 在 APP 中内嵌一个 H5 来实现特定的业务功能已经是非常成熟且常用的方案了。 虽然 H5 已经能够实现大多数的需求&#xff0c;但是对于某些需求还是得依靠原生代码来实现然后与 JavaScript 进行交互&#xff0c;例如我目前所负责的项目就是一个 “智能硬件” 设备&#x…

【PyTorch】卷积神经网络

文章目录 1. 理论介绍1.1. 从全连接层到卷积层1.1.1. 背景1.1.2. 从全连接层推导出卷积层 1.2. 卷积层1.2.1. 图像卷积1.2.2. 填充和步幅1.2.3. 多通道 1.3. 池化层&#xff08;又称汇聚层&#xff09;1.3.1. 背景1.3.2. 池化运算1.3.3. 填充和步幅1.3.4. 多通道 1.4. 卷积神经…

实现React18加TS,解决通用后台管理系统,实战方案落地有效实践经验

随着前端技术的不断发展和更新&#xff0c;使用React 18结合TypeScript&#xff08;TS&#xff09;来构建通用后台管理系统已成为一种常见的选择。本文将介绍如何在项目中应用React 18和TS&#xff0c;并分享一些实战方案的有效实践经验。 一、搭建React 18 TS项目 首先&…

12.2每日一题(1无穷型幂指函数:二倍角公式+三部曲+等价无穷小代换(只有整体的因子不为0才能先算出来))

注意&#xff1a;求极限不能想先算哪里就先算哪里&#xff0c;只有整体的因子不为0才能先算出来&#xff0c;部分不为0不可以先算

外贸老业务也棘手的一个问题

这几天有2个老业务都被一个类同的问题缠住了。 客户定购了三台车&#xff0c;由于是非常规要求所以我建议收取全款或者最少收50%的定金。但是业务员为了当月业绩或者为了拿到就收了客户20% 或者30% &#xff0c;定金收到了&#xff0c;我也不好再逼着业务员去加收定金。 订单就…

记录 | ubuntu上安装fzf

在 ubuntu 上采用命令行安装 fzf 的方式行不通 指的是采用下面的方式行不通&#xff1a; sudo apt install fzf # 行不通 sudo snap install fzf --classic # 行不通正确的安装方式是&#xff1a; ● 到 fzf 的 git 仓库&#xff1a;https://github.com/junegunn/fzf/re…

在高数据量中如何优化MySQL的Group by语句?

在实际开发环境中&#xff0c;MySQL的GROUP BY操作的优化需要结合具体的业务场景和数据特点。以下是一些建议&#xff0c;可以帮助你在实际开发中优化GROUP BY查询&#xff1a; 使用合适的索引&#xff1a; 确保GROUP BY和ORDER BY中的列上存在索引。这有助于加速分组和排序操作…

计算机毕业设计 基于SpringBoot的电动车租赁系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

场景示例:有赞商城 × 微盛企微管家,助力零售企业,实现私域运营自动化

1 场景描述 在零售行业内&#xff0c;线上渠道已经是零售行业的主要销售渠道&#xff0c;大多数零售企业都会将产品上架到有赞商城&#xff0c;并使用微盛企微管家系统进行客户管理和服务&#xff0c;希望能对客户画像进行精细化管理&#xff0c;以提升销售和服务效率。 然而&a…

2023年最新prometheus + grafana搭建和使用+gmail邮箱告警配置

一、安装prometheus 1.1 安装 prometheus官网下载地址 sudo -i mkdir -p /opt/prometheus #移动解压后的文件名到/opt/,并改名prometheus mv prometheus-2.45 /opt/prometheus/ #创建一个专门的prometheus用户&#xff1a; -M 不创建家目录&#xff0c; -s 不让登录 useradd…

女士内衣市场分析:预计2028年将达到643.08亿美元

内衣 (英文名:Underwear)&#xff0c;是指贴身穿的衣物。内衣有保暖及污秽的危害作用&#xff0c;有时会被视为性征。女士内衣行业生产的主要原料是各类织布或无纺布&#xff0c;成分有海绵、边、定型纱、骨胶、肩带等&#xff0c;布面料在内衣企业的生产成本中所占比重较大。女…

Python基础(四、探索迷宫游戏)

Python基础&#xff08;四、探索迷宫游戏&#xff09; 游戏介绍游戏说明 游戏介绍 在这个游戏中&#xff0c;你将扮演一个勇敢的冒险者&#xff0c;进入了一个神秘的迷宫。你的任务是探索迷宫的每个房间&#xff0c;并最终找到隐藏在其中的宝藏。 游戏通过命令行界面进行交互…

web 前端之标签练习+知识点

目录 实现过程&#xff1a; 结果显示 1、HTML语法 2、注释标签 3、常用标签 4、新标签 5、特殊标签 6、在网页中使用视频和音频、图片 7、表格标签 8、超链接标签 使用HTML语言来实现该页面 实现过程&#xff1a; <!DOCTYPE html> <html><head>…

泡沫包装市场分析:预计2029年将达到659亿元

泡沫包装&#xff0c;简单地讲&#xff0c;就是用数学方法对无线电测量或光学测量所获得的弹道数据进行检验、整理、校正、计算&#xff0c;减小或消除数据的误差&#xff0c;得出反映运载火箭运动轨迹的精确弹道参数。通常所说的泡沫包装&#xff0c;主要是指由可发性聚苯乙烯…