关闭AcceptEx缓冲区导致延迟增加问题

经测试,在AcceptEx函数指针投递accept请求的时候如果把接收缓冲区的大小设置为零,那么server端消息到client端延迟会增加10ms左右(各机器性能不同...)    上对比图

关闭了缓冲区的server端

 

client端

咱们先不看第一个client链接,因为程序启动耗时的原因,所以拿第二个举例, 第二个执行WSASend函数后的时间为1586760772134(1900年到现在的毫秒数),  客户端的到达时间为1586760772144, 共10毫秒, 由于本人做过多次试验,所以确定时间在10毫秒左右浮动,  接下来我们看正常缓冲区大小的收发用时

带缓冲区的server端

 

client端


大家可以看到,server端的发送消息时间和client端的接收消息时间都为1586761584231,0毫秒的延迟, 证明之前10毫秒的延迟是因为我们关闭了接收缓冲区造成的,不知道系统是怎么操作的..
       但是,很重要的是,设置接收缓冲区大小为0有一个好处,就是可以防止拒绝服务攻击(连接上后就不发消息的client),因为设置缓冲区大小为0后windows一收到连接请求就会通过GetQueuedCompletionStatus通知我们, 那么我们就可以尽快的做出处理,防止攻击, 而如果我们不设置缓冲区大小为0的话,windows的机制就会将两个操作合并为一个,哪两个操作呢,那就是accept和客户端发出的第一组数据,写过iocp的都知道,客户端连接的时候GetQueuedCompletionStatus并不会通知我们,而是在第一组数据发出的时候才通知我们,这是易用也是不易用的地方。
       之前还在网上看过一种方法,就是不设置缓冲区大小为0,但是定时用getsockopt()函数(选项参数为SO_CONNECT_TIME)来检查AcceptEx()里守候的套接字,可以看到套接字的连接时间或者状态,但是,如果是在高流量的情况下,那么这种方案就有点不太管用,还会阻塞其他用户的连接,所以,我建议还是设置缓冲区为0,就算会有一点延迟,但是会让我们的服务器更加安全。

      另外针对连接后的client端,在网上也看到一个比较好的处理方案,就是投递WSARecv后先将连接后客户端放入verctor或者list中,设定一个时间间隔定时检查超时的连接,及时关闭并删除其数据,如果同一ip出现次数过多就判断为恶意连接加入黑名单,如果接收到数据结构中的socket发出的数据的时候再将其从中移除放入正常的管理列表。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值