【计算机网络】——ET和LT模式

1、概念

在讲清楚这两个模式的概念之前,我们应该明确一下他们都是epoll对文件描述符的操作模式。LT(电平触发)和ET(边沿触发)。LT是默认的工作模式。在LT模式下epoll就相当于一个效率比较高的poll。如果我们想要在ET模式下来操作该文件描述符的话,就往该文件描述符上注册EPOLLET事件。就是event.events = EPOLLEF

  • LT:当epoll_wait检测到有事件发生并将此事件通知给应用程序过后,应用程序可以不立即处理该事件。这样当应用程序下一次调用epoll_wait的的时候,epoll_wait还会再次向应用程序通告此事件,直到该事件被处理
  • ET:当epoll_wait检测到有事件发生并将此事件通知给应用程序过后,应用程序必须立即处理该事件,因为后续的epoll_wait不会再次向此应用程序通知这一事件。

2、LT模式测试

在我们之前讲述的epoll.c的代码上做以下修改

修改接收数据的函数,每次只收一个字节:
即recv(fd,buff,5,0)

客户端代码还是不改变,运行两个客户端分别输入hello world 和this is linux。会出现下面这个结果:
在这里插入图片描述
从运行结果我们可以看到发送了一个大于5的数据,服务端每次只接受5个数据,那么epoll_wait()就会不断地提醒你,让你去处理,直至没有就绪事件。可以看到这种模式下epoll_wait()就被调用了多次,所以我们一般不使用它。

3、ET模式测试

我们往epoll内核事件表中注册一个文件描述符上的EPOLLET事件

event.events=EPOLLIN|EPOLLRDHUP|EPOLLET;

其他代码不变,运行结果如图所示:
在这里插入图片描述
从上面的运行结果我们可以看到,调用了两次一次是客户端连接,一次是处理hello。但是我们后面的wold数据去哪儿了呢?
首先可以肯定的是——肯定不在客户端缓冲区,因为send就表示发送过去了。所以在服务端的缓冲区中

由此,我们接下来再发送this is linux的时候就输出了wold.
在这里插入图片描述
从上面的运行结果我们可以看到它继续读缓冲区的数据。

  • 应用程序读数据的多少是由程序来决定的,读完了就完了。如果没有读完就存放在TCP的缓冲区中。
  • 如果缓冲区满了则send会阻塞。但是我们一般都会采取拥塞控制和滑动窗口来控制。

那我们如何来解决一直不能读到实时信息,都是缓冲区的问题呢,也就是说让他做到提醒一次,一次性处理完所有数据?由此我们引出了改进版的ET模式

4、改进ET模式

  • 首先,需要让它一次性把就绪事件都处理完。那么我们在处理数据处加个循环,一直处理。但是如果hello world两次都读完之后recv就会阻塞退不出循环,除非客户端关闭,因为他没有办法退出,这时I/O复用已经没有作用。
  • 为了让他处理完所有就绪事件可以退出,我们需要设计在获取事件描述符c后。将c设置成为非阻塞运行,这样recv就不会阻塞,则返回-1,并且会设置全局的errno。

如下,我们将c设置为非阻塞方式。关于fcntl函数的补充请参考博文fcntl

 int oldoption= fcntl(c,F_GETFL);
 int newoption=oldoption| O_NONBLOCK;//新的标志位设为非阻塞状态。
 fcntl(c,F_SETFL,newoption);//设置新的状态
  • 处理时要进行判断
if(errno==EAGAIN ||errno==EWOULDBLOCK)

如果 成立的话就表示没有数据可以读或者数据已经读取完毕,这时我们就可以退出循环。并且,只有读完了才给客户端发ok,不要读一次数据就发一次。
具体代码实现如下:

# define _GNU_SOURCE
# include<stdio.h>
# include<unistd.h>
# include<string.h>
# include<assert.h>

# include<sys/types.h>
# include<sys/socket.h>
# include<sys/epoll.h>
# include<arpa/inet.h>
# include<netinet/in.h>
# include<fcntl.h>
# include<errno.h>
# define MAXEVENTS 100

int InitSocket()
{
   
    int sockfd=socket(AF_INET,SOCK_STREAM,0);
    if(sockfd==
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值