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

中山网站建设找阿江培训课程开发

中山网站建设找阿江,培训课程开发,武汉电子商务网站建设公司,使用word做网站本文主要介绍TCP并发网络的编程,重点介绍io多路复用的epoll实现 一、TCP/IP 网络通信过程 要完成一个完整的 TCP/IP 网络通信过程,需要使用一系列函数来实现。这些函数包括 bind、listen、accept 和 recv/send 等。下面是它们的配合流程: 创…

本文主要介绍TCP并发网络的编程,重点介绍io多路复用的epoll实现

一、TCP/IP 网络通信过程

要完成一个完整的 TCP/IP 网络通信过程,需要使用一系列函数来实现。这些函数包括 bind、listen、accept 和 recv/send 等。下面是它们的配合流程:

  1. 创建套接字(socket):使用 socket 函数创建一个套接字,指定协议族和套接字类型。
  2. 绑定地址(bind):将本地地址绑定到套接字上,使得客户端可以通过该地址访问服务器。
  3. 监听连接请求(listen):将套接字设置为监听状态,并指定最大等待连接数(backlog)。
  4. 接受连接请求(accept):当有客户端发起连接请求时,使用 accept 函数创建新的套接字用于与客户端进行通信。
  5. 读写数据(recv/send):使用新创建的套接字进行数据传输,包括从客户端读取数据和向客户端发送数据。
  6. 关闭连接(close):在通信结束后,需要使用 close 函数关闭套接字以释放资源。

对于第4步的请求有两种处理方式:一线程一请求和epoll方法。

二、io多路复用的epoll 实现

epoll是一种在Linux操作系统中实现高性能I/O多路复用的机制。它可以同时监听多个文件描述符,当其中任何一个文件描述符发生读写等事件时,就会触发相应的回调函数进行处理。
基于 epoll 实现的 TCP 服务端程序的流程如下:

  1. 创建一个监听套接字,使用 socket() 函数创建套接字并设置相关参数(如地址重用等)。

  2. 将监听套接字绑定到本地 IP 地址和端口号,使用 bind() 函数将套接字与指定的地址进行绑定。

  3. 开始监听连接请求,使用 listen() 函数将该套接字标记为被动监听状态,并设置可同时处理的最大连接数。

  4. 创建一个 epoll 实例,使用 epoll_create() 函数创建 epoll 实例,并设置需要监视的事件类型。

  5. 将监听套接字添加到 epoll 实例中,使用 epoll_ctl() 函数向 epoll 实例中添加需要监视的文件描述符及对应事件。其中事件类型一般为 EPOLLIN 表示可读事件或者 EPOLLERR 表示错误事件。

  6. 进入主循环处理客户端请求,使用 epoll_wait() 等待内核通知就绪事件,并获取到就绪的文件描述符列表。然后遍历这个文件描述符列表并根据每个文件描述符对应的事件类型进行相应处理。如果是新连接请求,则调用 accept() 接收该连接,并将其加入 epoll 监听队列;否则,直接读取数据或者关闭连接等操作。

  7. 关闭监听套接字以及已经建立连接的客户端套接字,清理资源并退出程序。

总之,在 epoll 实现的 TCP 服务端程序中,通过使用 epoll 实例,可以同时处理多个客户端连接请求,并且在有新数据到达时能够及时地通知程序进行相应的处理。

另外,epoll还提供了ET(边缘触发)和LT(水平触发)两种工作模式。

  1. 水平触发模式
    在水平触发模式下,如果文件描述符上的事件没有被处理完毕,epoll 会持续通知应用程序该文件描述符上仍有事件待处理。在这种情况下,如果应用程序不及时响应并读取数据,则 epoll 会一直通知应用程序该文件描述符上有数据可读取。
  2. 边沿触发模式
    在边沿触发模式下,只要文件描述符上出现新的事件(例如数据可读或连接建立),epoll 就会通知应用程序。但是,在通知之后,如果应用程序没有立即响应并读取所有数据,则 epoll 不会再次通知该文件描述符上有新的数据可读。

总体来说,边沿触发模式相比于水平触发模式更为高效,并且可以避免由于重复监听导致 CPU 占用率过高的问题。但是,在使用边沿触发模式时需要注意及时读取所有数据,并确保每个事件都得到了正确处理。

并且,与select相比,虽然两者都是Linux下的I/O多路复用机制,但是它们有一些重要的区别:

  • 监听文件描述符数量限制不同:在Linux中,select函数所支持的最大文件描述符数量默认为1024个,而epoll没有这个限制,可以监听成千上万个文件描述符。

  • 文件描述符集合拷贝方式不同:在使用select时,每次调用需要将待监视的所有文件描述符从用户空间拷贝到内核空间,在返回结果之后还需要再将结果从内核空间拷贝回用户空间。这样会带来较大的性能开销。而在使用epoll时,只需将待监视的文件描述符加入一个内核事件表中即可完成注册,当有就绪事件发生时直接通知应用程序进行处理。

  • 对于非阻塞套接字处理方式不同:在使用select时,对于非阻塞套接字我们需要手动设置为非阻塞模式并且轮询读写操作是否就绪。而epoll则通过设置EPOLLET标志位实现了边缘触发模式,并且对于非阻塞套接字只需要等待其返回EAGAIN错误码即可知道其已经处于非阻塞状态。

总体来说,与select相比,epoll具有更高效、更灵活、更易扩展等优点,在处理大量并发连接时具有更好的性能和可扩展性。


#include <stdio.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>// #include <winsock2.h>
// #include <mswsock.h>
// #include <windows.h>
// #include <sys/types.h>  
// #include <unistd.h>
// #include <fcntl.h>#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <pthread.h>
#include <errno.h>
#include <fcntl.h> 
#include <unistd.h> 
#include <sys/epoll.h>#define BUFFER_LENGTH       1024
#define EPOLL_SIZE          1024void *client_routine(void *arg){int clientfd=*(int *)arg;while (1){char buffer[BUFFER_LENGTH]={0};int len=recv(clientfd,buffer,BUFFER_LENGTH,0);if (len < 0){//非阻塞状态下读到空数据close(clientfd);break;}else if(len == 0) {//断开连接close(clientfd);break;}else{printf("Recv: %s, %d btye(s)\n",buffer,len);}}
}int main(int argc,char *argv[]){if (argc < 2) {printf("Param Error \n");return -1;}int port=atoi(argv[1]);//atoi将一个字符串转换为对应的整数值int sockfd=socket(AF_INET,SOCK_STREAM,0);struct sockaddr_in addr;memset(&addr,0,sizeof(struct sockaddr_in));addr.sin_family=AF_INET;addr.sin_port=htons(port);addr.sin_addr.s_addr=INADDR_ANY;if (bind(sockfd,(struct sockaddr*)&addr,sizeof(struct sockaddr_in))<0){perror("bind");return -2;}if(listen(sockfd,5)<0){perror("listen");return -3;}#if 0// 一请求一线程while (1){  struct sockaddr_in client_addr;memset(&client_addr,0,sizeof(struct sockaddr_in));socklen_t client_len =sizeof(client_addr);/*调用 accept() 函数后,它会一直阻塞等待直到有新的客户端连接请求到达为止。当有新的连接请求到达时,它会返回一个新产生的套接字文件描述符,并且将该连接对应的客户端地址信息存储在 addr 指向的结构体中*/int clientfd=accept(sockfd,(struct sockaddr *)&client_addr,&client_len);pthread_t thread_id;pthread_create(&thread_id,NULL,client_routine,&clientfd);}#else     /*使用epoll的基本流程如下:1,创建一个epoll实例,可以通过调用 epoll_create() 函数来创建。2,向 epoll 实例中添加需要监控的文件描述符及其事件类型,可以通过调用 epoll_ctl() 函数进行操作。3,调用 epoll_wait() 函数等待监控对象上发生事件,并处理活跃的文件描述符及其事件类型。4,处理完活跃文件描述符的相关操作后,返回到第三步继续等待新的事件发生。*/int epfd=epoll_create(1);   struct epoll_event events[EPOLL_SIZE] = {0};    //创建一个结构体数组 events 用于存储 epoll_wait() 返回的事件列表。struct epoll_event ev;  ev.events=EPOLLIN;  //创建一个新的 epoll_event 结构体 ev 并设置其关注的事件类型为 EPOLLIN (表示等待读事件)ev.data.fd = sockfd;epoll_ctl(epfd,EPOLL_CTL_ADD,sockfd,&ev);   //使用 epoll_ctl() 函数将 sockfd 文件描述符加入到 epfd 实例中,并关联上面创建的 ev 结构体。while (1){int nready=epoll_wait(epfd,events,EPOLL_SIZE,5); //if (nready == -1) continue; //表示5秒内,没有事件,继续监听int i=0;for (i=0;i<nready;i++){/*判断当前事件所对应的文件描述符是否为监听套接字 sockfd。如果是,则说明有新的客户端连接请求到来了,需要通过 accept() 函数获取新产生的客户端连接并添加到 epoll 实例中;否则,说明是已经建立好连接的客户端发送了数据,需要通过 recv() 函数接收数据并进行相应处理。*/if(events[i].data.fd == sockfd){/*当有新的连接请求到来时(即 sockfd 上有 EPOLLIN 事件),使用 accept() 函数接受连接,并将其加入 epoll 实例中关注该套接字上是否有输入事件。*/struct sockaddr_in client_addr;memset(&client_addr,0,sizeof(struct sockaddr_in));socklen_t client_len =sizeof(client_addr);int clientfd=accept(sockfd,(struct sockaddr *)&client_addr,&client_len);ev.events=EPOLLIN | EPOLLET;  //EPOLLET 则表示将 I/O 事件设置为边缘触发模式。ev.data.fd=clientfd;epoll_ctl(epfd,EPOLL_CTL_ADD,clientfd,&ev);}else{//当某个客户端套接字上出现可读事件时(即该文件描述符在 events 中对应的元素有 EPOLLIN 标志),则调用 recv() 函数从该套接字中读取数据int clientfd=events[i].data.fd;char buffer[BUFFER_LENGTH]={0};int len=recv(clientfd,buffer,BUFFER_LENGTH,0);if (len < 0){//出现了异常情况或者非阻塞状态下没有更多数据可读//关闭该套接字并将其从 epoll 实例中删除close(clientfd);ev.events=EPOLLIN;  ev.data.fd=clientfd;epoll_ctl(epfd,EPOLL_CTL_DEL,clientfd,&ev); //从 epoll 实例中删除 clientfd 对应的文件描述符,并且停止监听该套接字上的事件。}else if(len == 0) {//对方已经断开连接//关闭该套接字并将其从 epoll 实例中删除close(clientfd);ev.events=EPOLLIN;  ev.data.fd=clientfd;epoll_ctl(epfd,EPOLL_CTL_DEL,clientfd,&ev);}else{printf("Recv: %s, %d btye(s)\n",buffer,len);}}}}#endifreturn 0;
}
http://www.dinnco.com/news/44659.html

相关文章:

  • 兰溪做网站淮安网站seo
  • 网站推广工作总结seo技术论坛
  • 精品建设课程网站关键词挖掘爱站网
  • 阜宁做网站工作室河北seo技术交流
  • wordpress 大前端2.0手机关键词seo排名优化
  • 网站怎样快速排名长沙网站制作
  • wordpress模板学校网站seo优化免费
  • 刚开始做网站要传数据库吗域名查询138ip
  • 淘宝客网站怎样做seo营销软文范例
  • 网站建设费计入无形资产网络营销品牌案例
  • 滕州网站建设制作含有友情链接的网页
  • cms网站开发营销软文范例大全300字
  • 服务器网站开发网易疫情实时最新数据
  • 手游制作软件上海seo推广平台
  • 如何建设网站的能力搜索引擎营销案例有哪些
  • 网站建设业务员沟通需求建站模板
  • 四川学校网站建设做竞价托管的公司
  • 长春网站优化指导今日国内新闻10则
  • 响应式网站生成免费个人网站服务器
  • 怎么做购物平台网站百度客服人工电话24
  • 网站版权该怎么做呢独立站建站平台有哪些
  • h5响应式网站开发百度推广手机版
  • 巴彦淖尔市做网站公司网址查询服务器地址
  • vs2013可以做网站么网络营销推广活动有哪些
  • 大兴企业官网网站建设咨询有品质的网站推广公司
  • 网上接做网站的单子温州seo团队
  • 数字博物馆网站建设百度搜索热词排行榜
  • 物流网站建设方案权限管理软件外包公司
  • 购物网站建设项目策划书江苏网页设计
  • 多语种外贸网站网站搭建公司哪家好