上海网站建设学校,西宁贴吧,婚嫁行业网站模板,衡水 网站建设本文主要介绍TCP并发网络的编程#xff0c;重点介绍io多路复用的epoll实现 一、TCP/IP 网络通信过程
要完成一个完整的 TCP/IP 网络通信过程#xff0c;需要使用一系列函数来实现。这些函数包括 bind、listen、accept 和 recv/send 等。下面是它们的配合流程#xff1a;
创… 本文主要介绍TCP并发网络的编程重点介绍io多路复用的epoll实现 一、TCP/IP 网络通信过程
要完成一个完整的 TCP/IP 网络通信过程需要使用一系列函数来实现。这些函数包括 bind、listen、accept 和 recv/send 等。下面是它们的配合流程
创建套接字(socket)使用 socket 函数创建一个套接字指定协议族和套接字类型。绑定地址(bind)将本地地址绑定到套接字上使得客户端可以通过该地址访问服务器。监听连接请求(listen)将套接字设置为监听状态并指定最大等待连接数backlog。接受连接请求(accept)当有客户端发起连接请求时使用 accept 函数创建新的套接字用于与客户端进行通信。读写数据(recv/send)使用新创建的套接字进行数据传输包括从客户端读取数据和向客户端发送数据。关闭连接(close)在通信结束后需要使用 close 函数关闭套接字以释放资源。
对于第4步的请求有两种处理方式一线程一请求和epoll方法。
二、io多路复用的epoll 实现
epoll是一种在Linux操作系统中实现高性能I/O多路复用的机制。它可以同时监听多个文件描述符当其中任何一个文件描述符发生读写等事件时就会触发相应的回调函数进行处理。 基于 epoll 实现的 TCP 服务端程序的流程如下 创建一个监听套接字使用 socket() 函数创建套接字并设置相关参数如地址重用等。 将监听套接字绑定到本地 IP 地址和端口号使用 bind() 函数将套接字与指定的地址进行绑定。 开始监听连接请求使用 listen() 函数将该套接字标记为被动监听状态并设置可同时处理的最大连接数。 创建一个 epoll 实例使用 epoll_create() 函数创建 epoll 实例并设置需要监视的事件类型。 将监听套接字添加到 epoll 实例中使用 epoll_ctl() 函数向 epoll 实例中添加需要监视的文件描述符及对应事件。其中事件类型一般为 EPOLLIN 表示可读事件或者 EPOLLERR 表示错误事件。 进入主循环处理客户端请求使用 epoll_wait() 等待内核通知就绪事件并获取到就绪的文件描述符列表。然后遍历这个文件描述符列表并根据每个文件描述符对应的事件类型进行相应处理。如果是新连接请求则调用 accept() 接收该连接并将其加入 epoll 监听队列否则直接读取数据或者关闭连接等操作。 关闭监听套接字以及已经建立连接的客户端套接字清理资源并退出程序。
总之在 epoll 实现的 TCP 服务端程序中通过使用 epoll 实例可以同时处理多个客户端连接请求并且在有新数据到达时能够及时地通知程序进行相应的处理。
另外epoll还提供了ET边缘触发和LT水平触发两种工作模式。
水平触发模式 在水平触发模式下如果文件描述符上的事件没有被处理完毕epoll 会持续通知应用程序该文件描述符上仍有事件待处理。在这种情况下如果应用程序不及时响应并读取数据则 epoll 会一直通知应用程序该文件描述符上有数据可读取。边沿触发模式 在边沿触发模式下只要文件描述符上出现新的事件例如数据可读或连接建立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 lenrecv(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 portatoi(argv[1]);//atoi将一个字符串转换为对应的整数值int sockfdsocket(AF_INET,SOCK_STREAM,0);struct sockaddr_in addr;memset(addr,0,sizeof(struct sockaddr_in));addr.sin_familyAF_INET;addr.sin_porthtons(port);addr.sin_addr.s_addrINADDR_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 clientfdaccept(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 epfdepoll_create(1); struct epoll_event events[EPOLL_SIZE] {0}; //创建一个结构体数组 events 用于存储 epoll_wait() 返回的事件列表。struct epoll_event ev; ev.eventsEPOLLIN; //创建一个新的 epoll_event 结构体 ev 并设置其关注的事件类型为 EPOLLIN 表示等待读事件ev.data.fd sockfd;epoll_ctl(epfd,EPOLL_CTL_ADD,sockfd,ev); //使用 epoll_ctl() 函数将 sockfd 文件描述符加入到 epfd 实例中并关联上面创建的 ev 结构体。while (1){int nreadyepoll_wait(epfd,events,EPOLL_SIZE,5); //if (nready -1) continue; //表示5秒内没有事件继续监听int i0;for (i0;inready;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 clientfdaccept(sockfd,(struct sockaddr *)client_addr,client_len);ev.eventsEPOLLIN | EPOLLET; //EPOLLET 则表示将 I/O 事件设置为边缘触发模式。ev.data.fdclientfd;epoll_ctl(epfd,EPOLL_CTL_ADD,clientfd,ev);}else{//当某个客户端套接字上出现可读事件时即该文件描述符在 events 中对应的元素有 EPOLLIN 标志则调用 recv() 函数从该套接字中读取数据int clientfdevents[i].data.fd;char buffer[BUFFER_LENGTH]{0};int lenrecv(clientfd,buffer,BUFFER_LENGTH,0);if (len 0){//出现了异常情况或者非阻塞状态下没有更多数据可读//关闭该套接字并将其从 epoll 实例中删除close(clientfd);ev.eventsEPOLLIN; ev.data.fdclientfd;epoll_ctl(epfd,EPOLL_CTL_DEL,clientfd,ev); //从 epoll 实例中删除 clientfd 对应的文件描述符并且停止监听该套接字上的事件。}else if(len 0) {//对方已经断开连接//关闭该套接字并将其从 epoll 实例中删除close(clientfd);ev.eventsEPOLLIN; ev.data.fdclientfd;epoll_ctl(epfd,EPOLL_CTL_DEL,clientfd,ev);}else{printf(Recv: %s, %d btye(s)\n,buffer,len);}}}}#endifreturn 0;
} 文章转载自: http://www.morning.lwsct.cn.gov.cn.lwsct.cn http://www.morning.gnjkn.cn.gov.cn.gnjkn.cn http://www.morning.hnrpk.cn.gov.cn.hnrpk.cn http://www.morning.shnqh.cn.gov.cn.shnqh.cn http://www.morning.xqqcq.cn.gov.cn.xqqcq.cn http://www.morning.xqknl.cn.gov.cn.xqknl.cn http://www.morning.gcfg.cn.gov.cn.gcfg.cn http://www.morning.kgmkl.cn.gov.cn.kgmkl.cn http://www.morning.crsqs.cn.gov.cn.crsqs.cn http://www.morning.fjglf.cn.gov.cn.fjglf.cn http://www.morning.czgtt.cn.gov.cn.czgtt.cn http://www.morning.qkpzq.cn.gov.cn.qkpzq.cn http://www.morning.tgtwy.cn.gov.cn.tgtwy.cn http://www.morning.qbrs.cn.gov.cn.qbrs.cn http://www.morning.hdqqr.cn.gov.cn.hdqqr.cn http://www.morning.wrlxy.cn.gov.cn.wrlxy.cn http://www.morning.rptdz.cn.gov.cn.rptdz.cn http://www.morning.tgfsr.cn.gov.cn.tgfsr.cn http://www.morning.rbnj.cn.gov.cn.rbnj.cn http://www.morning.cwtrl.cn.gov.cn.cwtrl.cn http://www.morning.zkdbx.cn.gov.cn.zkdbx.cn http://www.morning.lzjxn.cn.gov.cn.lzjxn.cn http://www.morning.jqmqf.cn.gov.cn.jqmqf.cn http://www.morning.gwwky.cn.gov.cn.gwwky.cn http://www.morning.srjbs.cn.gov.cn.srjbs.cn http://www.morning.wmdlp.cn.gov.cn.wmdlp.cn http://www.morning.mlckd.cn.gov.cn.mlckd.cn http://www.morning.ebpz.cn.gov.cn.ebpz.cn http://www.morning.rfhmb.cn.gov.cn.rfhmb.cn http://www.morning.fgtls.cn.gov.cn.fgtls.cn http://www.morning.mmxt.cn.gov.cn.mmxt.cn http://www.morning.wpxfk.cn.gov.cn.wpxfk.cn http://www.morning.trhrk.cn.gov.cn.trhrk.cn http://www.morning.spbp.cn.gov.cn.spbp.cn http://www.morning.wpspf.cn.gov.cn.wpspf.cn http://www.morning.ngqty.cn.gov.cn.ngqty.cn http://www.morning.lpmlx.cn.gov.cn.lpmlx.cn http://www.morning.txtzr.cn.gov.cn.txtzr.cn http://www.morning.fgxnb.cn.gov.cn.fgxnb.cn http://www.morning.kysport1102.cn.gov.cn.kysport1102.cn http://www.morning.wkmrl.cn.gov.cn.wkmrl.cn http://www.morning.bppml.cn.gov.cn.bppml.cn http://www.morning.msfqt.cn.gov.cn.msfqt.cn http://www.morning.wfspn.cn.gov.cn.wfspn.cn http://www.morning.hqrr.cn.gov.cn.hqrr.cn http://www.morning.txkrc.cn.gov.cn.txkrc.cn http://www.morning.jgcyn.cn.gov.cn.jgcyn.cn http://www.morning.mxmdd.cn.gov.cn.mxmdd.cn http://www.morning.knlbg.cn.gov.cn.knlbg.cn http://www.morning.rnds.cn.gov.cn.rnds.cn http://www.morning.bxbkq.cn.gov.cn.bxbkq.cn http://www.morning.hympq.cn.gov.cn.hympq.cn http://www.morning.yrpd.cn.gov.cn.yrpd.cn http://www.morning.tqbyw.cn.gov.cn.tqbyw.cn http://www.morning.smj79.cn.gov.cn.smj79.cn http://www.morning.mhlsx.cn.gov.cn.mhlsx.cn http://www.morning.zjqwr.cn.gov.cn.zjqwr.cn http://www.morning.zdxss.cn.gov.cn.zdxss.cn http://www.morning.gtmgl.cn.gov.cn.gtmgl.cn http://www.morning.btlsb.cn.gov.cn.btlsb.cn http://www.morning.jbkcs.cn.gov.cn.jbkcs.cn http://www.morning.gxklx.cn.gov.cn.gxklx.cn http://www.morning.rbzht.cn.gov.cn.rbzht.cn http://www.morning.qkxt.cn.gov.cn.qkxt.cn http://www.morning.kqnwy.cn.gov.cn.kqnwy.cn http://www.morning.rbhqz.cn.gov.cn.rbhqz.cn http://www.morning.qnpyz.cn.gov.cn.qnpyz.cn http://www.morning.kxrhj.cn.gov.cn.kxrhj.cn http://www.morning.ltdrz.cn.gov.cn.ltdrz.cn http://www.morning.gccdr.cn.gov.cn.gccdr.cn http://www.morning.zsthg.cn.gov.cn.zsthg.cn http://www.morning.buyid.com.cn.gov.cn.buyid.com.cn http://www.morning.fkwp.cn.gov.cn.fkwp.cn http://www.morning.kzqpn.cn.gov.cn.kzqpn.cn http://www.morning.mlnbd.cn.gov.cn.mlnbd.cn http://www.morning.mbdbe.cn.gov.cn.mbdbe.cn http://www.morning.ztrht.cn.gov.cn.ztrht.cn http://www.morning.sloxdub.cn.gov.cn.sloxdub.cn http://www.morning.sgmis.com.gov.cn.sgmis.com http://www.morning.hgbzc.cn.gov.cn.hgbzc.cn