当前位置: 首页 > wzjs >正文

日本做衣服的网站推广论坛有哪些

日本做衣服的网站,推广论坛有哪些,品牌推广的步骤和技巧,优惠券个人网站怎么做天天开心!!! 文章目录 一、如何实现一对一聊天?1. 服务器设计2. 客户端设计3. 服务端代码实现4. 客户端代码实现5. 实现说明6.实验结果 二、改进常见的服务器高并发方案1. 多线程/多进程模型2. I/O多路复用3. 异步I/O(…

天天开心!!!

文章目录

  • 一、如何实现一对一聊天?
    • 1. 服务器设计
    • 2. 客户端设计
    • 3. 服务端代码实现
    • 4. 客户端代码实现
    • 5. 实现说明
    • 6.实验结果
  • 二、改进
    • 常见的服务器高并发方案
    • 1. 多线程/多进程模型
    • 2. I/O多路复用
    • 3. 异步I/O(Asynchronous I/O)
    • 4. 事件驱动框架
    • 5. Reactor模式
    • 6. Proactor模式
    • 7. 协程(Coroutine)
  • 三、使用epoll改进Server服务端代码
    • 1. epoll基本工作流程
    • 2. 服务端的实现思路
    • 3. 改良后的具体实现代码
    • 实验结果:
    • 4. 实现说明
    • 5. 优势


一、如何实现一对一聊天?

在C++的Socket编程中,实现一对一聊天的基本思路是构建一个客户端(Client)和一个服服务端(Server),并让每个客户端之间通过服务器进行消息的转发,具体步骤如下:

1. 服务器设计

服务器愮接受多个客户端的连接,并为每对用户建立专属的通信通道,实现流程如下:

  • 服务端启动并监听某个端口
  • 每当有客户端连接时,服务端接受连接并创建一个独立的线程或使用I/O多路复用(如select、epoll)来处理客户端请求。
  • 服务端维护一个客户端的连接表(这里我们使用map来存储),当两个客户端匹配时,将彼此的消息进行转发
  • 实现聊天消息的收发和转发逻辑

2. 客户端设计

客户端需要与服务器保持连接,并能够持续地发送和接收消息。实现流程如下:

  • 客户端启动后,连接到服务端指定的IP和端口
  • 客户端可以发送消息给服务端,服务端将消息转发给目标用户
  • 客户端持续接收从服务器发送来的消息,显示在用户界面或控制台

3. 服务端代码实现

#include <iostream>
#include <cstring>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <thread>
#include <map>#define PORT 8080
#define BUFFER_SIZE 1024std::map<int,int> client_map; //存储客户端的配对关系//处理客户端通信
void handle_client(int client_socket){char buffer[BUFFER_SIZE];int target_socket=client_map[client_socket];  //获取配对的客户端socketwhile(true){memset(buffer,0,sizeof(buffer));//清空缓冲区ssize_t bytes_received=recv(client_socket,buffer,BUFFER_SIZE,0);//接收数据的长度if(bytes_received<=0){//如果接收失败,则关闭连接std::cerr<<"Error receiving data from client"<<std::endl;//输出错误信息close(client_socket);return;}std::cout<<"收到消息:"<<buffer<<std::endl;//将消息转发给目标客户端if(client_map.find(target_socket)!=client_map.end()){send(target_socket,buffer, strlen(buffer),0);}else{std::cerr<<"Error sending data to target client"<<std::endl;}}
}int main()
{int server_socket;struct sockaddr_in server_addr;//创建服务器套接字server_socket=socket(AF_INET,SOCK_STREAM,0);if(server_socket==0){std::cerr<<"Error creating server socket"<<std::endl;return -1;}//初始化地址结构server_addr.sin_family=AF_INET;server_addr.sin_addr.s_addr=INADDR_ANY;server_addr.sin_port=htons(PORT);//绑定地址和端口if(bind(server_socket,(struct sockaddr*)&server_addr,sizeof(server_addr))<0){std::cerr<<"Error binding server socket"<<std::endl;return -1;}//监听客户端连接if(listen(server_socket,3)<0){std::cerr<<"Error listening for connections"<<std::endl;return -1;}std::cout<<"等待客户端连接..."<<std::endl;while(true){struct sockaddr_in client_addr;socklen_t addr_len=sizeof(client_addr);int new_socket=accept(server_socket,(struct sockaddr*)&client_addr,&addr_len);if(new_socket<0){std::cerr<<"Error accepting connection"<<std::endl;continue;}std::cout<<"新客户端连接"<<inet_ntoa(client_addr.sin_addr)<<std::endl;//这里为了简化,我们直接假设是两客户端配对,client_map存储配对关系if(client_map.empty()){client_map[new_socket]=-1;//第一个客户端,暂时没有配对}else{for(auto &pair:client_map){if(pair.second==-1){client_map[new_socket]=pair.first;//第二个客户端与第一个客户端配对client_map[pair.first]=new_socket;//第一个客户端与第二个客户端配对std::cout<<"客户端配对成功"<<std::endl;break;}}}//创建线程处理新客户端std::thread client_thread(handle_client,new_socket);client_thread.detach();//线程分离,主线程不阻塞}close(server_socket);return 0;
}

4. 客户端代码实现

#include <iostream>
#include <cstring>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <thread>#define PORT 8080
#define BUFFER_SIZE 1024//处理服务器消息
void receive_message(int socket){char buffer[BUFFER_SIZE];while(true){memset(buffer, 0, sizeof(buffer));//清空缓冲区ssize_t bytes_received = recv(socket, buffer, BUFFER_SIZE, 0);if(bytes_received <= 0){std::cout << "服务器断开连接..." << std::endl;close(socket);return;}std::cout<<"收到消息:"<<buffer<<std::endl;}
}int main()
{int client_socket;//客户端套接字struct sockaddr_in server_addr;//创建客户端套接字client_socket=socket(AF_INET, SOCK_STREAM, 0);if(client_socket<0){std::cout<<"创建套接字失败"<<std::endl;return -1;}//初始化服务器地址server_addr.sin_family=AF_INET;server_addr.sin_port=htons(PORT);server_addr.sin_addr.s_addr=inet_addr("127.0.0.1");//服务器IP//连接到服务器if(connect(client_socket,(struct sockaddr*)&server_addr,sizeof(server_addr))<0){std::cerr<<"连接服务器失败"<<std::endl;return -1;}std::cout<<"连接到服务器成功"<<std::endl;//创建线程接受服务器消息std::thread receive_thread(receive_message,client_socket);//创建线程(函数,函数的形参)receive_thread.detach();//线程分离,主线程结束后,子线程也结束//发送消息给服务器char message[BUFFER_SIZE];while(true){std::cout<<"请输入消息:";std::cin.getline(message,BUFFER_SIZE);send(client_socket,message,strlen(message),0);}close(client_socket);return 0;
}

5. 实现说明

  • 服务端:服务器监听客户端连接并维护一个客户端配对表client_map;当两个客户端配对后,消息就可以在它们之间转发。这里使用了多线程来处理每个客户端的通信
  • 客户端:客户端连接到服务器并启动一个线程用于接收来自服务器的消息,用户可以输入消息并发送给服务器,服务器负责转发消息给配对的客户端

6.实验结果

在这里插入图片描述

二、改进

我们可以使用epoll或者select替代多线程处理,提高服务器的并发性能。也可以增加心跳机制来检测客户端是否断开连接。如果要完善,还可以增加实现身份验证和聊天室功能,使得用户可以自由选择与谁聊天。

常见的服务器高并发方案

1. 多线程/多进程模型

每个连接由一个独立的线程或进程处理,能够比较简单的实现并发处理

  • 优点:代码易于理解,编写较为简单
  • 缺点:线程或进程的开销较大,在高并发场景下,大量的线程/进程会带来系统资源消耗和性能瓶颈,特别是在数千甚至数万个连接的时候

2. I/O多路复用

I/O多路复用可通过少量的线程处理大量并发连接,常用的方法包括:

  • select:通过一个文件描述符集合监视多个文件描述符是否有I/O事件
    (1)优点:简单、易用、跨平台支持好
    (2) 缺点:性能不佳,处理大量连接时,每次调用select都要遍历整个描述符集合,效率很低

  • poll:与select类似,但没有文件描述符限制
    (1)优点:避免了select的文件描述符限制
    (2) 缺点:与select雷系,性能仍然不高,遍历整个描述符集合

  • epoll(Linux专用):epoll是Linux特有的I/O多路复用机制,性能更好,适合处理大量并发连接
    (1)优点:不会遍历所有文件描述符,性能优异,适用于高并发场景
    (2) 缺点:仅限于Linux系统

3. 异步I/O(Asynchronous I/O)

异步I/O通过事件驱动机制,程序不需要等待I/O操作的完成,而是注册事件,事件触发时进行处理。常见的异步I/O实现包括:

  • Windows:使用IOCP(I/O Completion Port)实现异步I/O处理
  • Linux:可以使用libaio或者基于epoll实现的异步I/O
  • 优点:真正的异步,无需阻塞等待I/O操作,性能高,适合高并发
  • 缺点:编写异步代码比较复杂,调试很困难

4. 事件驱动框架

利用现成的事件驱动框架来处理高并发来凝结,常见的库包括

  • libevent:基于事件的异步I/O库,支持epoll、kqueue等多种I/O多路复用机制,适合处理大量并发连接
  • libuv:跨平台异步I/O库,Node.js就是基于libuv实现的
  • Moduo:C++高性能网络库,基于epoll和线程池,适用于Linux下的高并发场景
  • 优点:封装好、使用方便,能够提高并发效率
  • 缺点:引入了额外的依赖,性能调优相对不够灵活

5. Reactor模式

Reactor模式是I/O多路复用的一种常见的实现模式,它通过注册I/O事件,将事件分发给事件处理器

  • 典型实现:使用epoll或select监听事件,再结合事件处理回调函数进行处理
  • 优点:能够较好地处理大量并发连接,灵活性高
  • 缺点:编写和理解较为复杂,需要维护事件循环和回调函数

6. Proactor模式

Proactor模式是异步I/O的常见实现,区别于Reactor,Proactor是I/O操作完成后再进行回调

  • 典型实现:Windows上的ICP就是Proactor模式实现的
  • 优点:异步操作更加彻底。I/O操作由操作系统处理,减少了用户态的干预
  • 缺点:实现较为复杂,调试难

7. 协程(Coroutine)

协程是一种轻量级的线程,能够在用户态进行切换,使用协程可以避免线程切换的开销,同时实现高并发。可以结合I/O多路复用技术,如epoll,来实现高效的协程并发

  • 典型框架:如Boost.Asio支持协程、libgo协程库等
  • 优点:切换开销小、性能高,代码易于理解
  • 缺点:调试比较复杂,尤其实在上下文切换时容易出现问题

三、使用epoll改进Server服务端代码

使用epoll实现一对一聊天的服务端,可以大大提高服务器的并发处理能力,相比于传统的多线程或select,epoll更适合处理大量客户端的连接,尤其是在高并发场景下。

1. epoll基本工作流程

  • 创建epoll文件描述符:使用epoll_create创建epoll实例
  • 注册事件:通过epoll_ctl将套接字添加到epoll实例中,并设置要监听的事件(如EPOLLIN,表示有数据可读)
  • 等待事件:使用epoll_wait等待事件发生
  • 处理事件:一旦事件发生,处理相应的客户端读写操作

2. 服务端的实现思路

  • 启动epoll实例:监听客户端的连接请求
  • 当有新的客户端连接时,将其注册到epoll实例中
  • 维护客户端配对关系:服务端为每个客户端建立配对表
  • 消息的收发和转发:当接收到某个客户端的消息时,通过配对表找到对应的目标客户端,并将消息转发过去

3. 改良后的具体实现代码

#include <iostream>
#include <string>
#include <cstring>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <map>
#include <sys/epoll.h>  // epoll头文件#define PORT 8080
#define BUFFER_SIZE 1024
#define MAX_EVENTS 10std::map<int,int> client_map;//客户端配对表int main(){int server_socket,epoll_fd;// 服务器套接字,epoll文件描述符struct sockaddr_in server_addr; // 服务器地址结构体//创建服务器套接字server_socket = socket(AF_INET, SOCK_STREAM, 0);if(server_socket <0){std::cerr << "创建服务器套接字失败" << std::endl;return -1;}//设置地址复用int opt=1;setsockopt(server_socket,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));//设置地址复用//初始化服务器地址server_addr.sin_family = AF_INET;server_addr.sin_addr.s_addr = INADDR_ANY;server_addr.sin_port = htons(PORT);//绑定地址到服务器套接字if(bind(server_socket,(struct sockaddr*)&server_addr,sizeof(server_addr))<0){std::cerr << "绑定地址到服务器套接字失败" << std::endl;return -1;}//监听端口if(listen(server_socket,10)<0){std::cerr << "监听端口失败" << std::endl;return -1;}//创建epoll实例epoll_fd = epoll_create1(0);if(epoll_fd ==-1){std::cerr<<"创建epoll实例失败"<<std::endl;return -1;}//将服务器套接字加入到epoll实例中struct epoll_event event;event.events = EPOLLIN;event.data.fd = server_socket;epoll_ctl(epoll_fd,EPOLL_CTL_ADD,server_socket,&event);std::cout<<"服务器启动成功,等待客户端连接...."<<std::endl;struct epoll_event events[MAX_EVENTS];  // epoll事件数组, 用于存储就绪事件while(true){//无限等待事件int event_count=epoll_wait(epoll_fd,events,MAX_EVENTS,-1);for(int i=0;i<event_count;i++){if(events[i].data.fd==server_socket){//处理新的客户端连接struct sockaddr_in client_addr;socklen_t clinet_len=sizeof(client_addr);int client_socket=accept(server_socket,(struct sockaddr*)&client_addr,&clinet_len);//接受客户端连接if(client_socket<0){std::cerr<<"接受客户端连接失败"<<std::endl;continue;}std::cout<<"新的客户端连接:"<<inet_ntoa(client_addr.sin_addr)<<std::endl;//将新客户端连接加入到epoll监听中event.events=EPOLLIN;event.data.fd=client_socket;epoll_ctl(epoll_fd,EPOLL_CTL_ADD,client_socket,&event);//客户端配对处理if(client_map.empty()){client_map[client_socket]=-1;//第一个客户端,暂时没有配对}else{for(auto &pair:client_map){if(pair.second==-1){client_map[client_socket]=pair.first;//找到第一个没有配对的客户端,进行配对client_map[pair.first]=client_socket;//更新第一个没有配对的客户端的配对信息break;}}}}else{//处理客户端的消息转发int client_socket=events[i].data.fd;char buffer[BUFFER_SIZE];memset(buffer,0,sizeof(buffer));//清空缓冲区ssize_t bytes_received=recv(client_socket,buffer,sizeof(buffer),0);//接收客户端消息if(bytes_received<=0){std::cerr<<"客户端断开连接"<<std::endl;epoll_ctl(epoll_fd,EPOLL_CTL_DEL,client_socket,NULL);//从epoll中删除该客户端close(client_socket);continue;}std::cout<<"收到的消息:"<<buffer<<std::endl;//转发消息给配对的客户端int target_socket=client_map[client_socket];if(target_socket!=-1){send(target_socket,buffer, strlen(buffer), 0);}else{std::cerr<<"目标客户端未连接"<<std::endl;}}}}close(server_socket);return 0;
}

实验结果:

在这里插入图片描述

4. 实现说明

  • epoll创建:通过epoll_create创建一个epoll实例,epoll_ctl用于将服务器套接字添加到epoll监听中
  • 事件处理:使用epoll_wait等待客户端连接事件和消息事件,一旦有事件发生,处理新连接或消息收发
  • 客户端配对:与之前的多线程版本类似,使用client_map维护客户端之间的配对关系

5. 优势

  • 高并发支持:epoll适合大量客户端并发连接,比select或多线程处理效率更高
  • 事件驱动:基于事件通知的机制,而不是轮询,降低了CPU使用率
  • 资源高效:无需为每个连接创建独立线程,减少了上下文切换的开销
http://www.dtcms.com/wzjs/525463.html

相关文章:

  • 求购做网站百度关键字
  • 网站用户访问统计百度首页推广广告怎么做
  • 延安网站建设网络公司跨境电商平台有哪些
  • 如何建导航网站重庆森林电影简介
  • 友汇网网站建设管理后台网站建设的数字化和互联网化
  • 建立公司安卓优化大师最新版
  • 阿里巴巴网站的pc端和手机端怎么做的公司怎么建立自己的网站
  • 模板网站外链做不起来沈阳市网站
  • 扁平风格 网站模板衡阳百度推广
  • 建设集团网站 技术支持中企动力网站历史权重查询
  • 企业网站开发模板抖音seo排名系统哪个好用
  • 广东做淘宝的都在哪里网站信阳seo
  • 网站开发树形图seo流量
  • 开发游戏学什么专业seo属于运营还是技术
  • wordpress 建站 域名seo优化的内容有哪些
  • 手机网站进不去怎么解决百度快速seo优化
  • 网站设计公司无锡企业网站优化的三层含义
  • 临沧网站建设公司招聘北京网站优化企业
  • 地产网站设计网站运营
  • 企业做网站有用吗本地广告推广平台哪个好
  • 环评怎么在网站做公示东莞关键词seo优化
  • 不错的网站建设公司seo排名优化
  • 专注合肥网站推广免费的推广引流软件
  • 罗定建设局网站竞价出价怎么出
  • 专业制作门牌武汉seo引擎优化
  • 江苏国龙翔建设网站google网页搜索
  • 吉林省建设部网站seo诊断方法步骤
  • phpcms网站开发市场营销证书含金量
  • 网站 规划方案站长素材音效
  • 网站开发凭证做什么科目搜易网优化的效果如何