`
dazhilao
  • 浏览: 246031 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

【转】对于linux socket与epoll配合相关的一些心得记录

阅读更多
原文地址:http://hi.baidu.com/netpet/blog/item/9a2cf83643355c370b55a9be.html
没有多少高深的东西,全当记录,虽然简单,但是没有做过测试还是挺容易让人糊涂的

     int nRecvBuf=32*1024;//设置为32K
setsockopt(s,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int));
1、通过上面语句可以简单设置缓冲区大小,测试证明:跟epoll结合的时候只有当单次发送的数据全被从缓冲区读完毕之后才会再次被触发,多次发送数据如果没有读取完毕当缓冲区未满的时候数据不会丢失,会累加到后面。
2、 如果缓冲区未满,同一连接多次发送数据会多次收到EPOLLIN事件。
单次发送数据>socket缓冲区大小的数据数据会被阻塞分次发送,所以循环接收可以用ENLIGE错误判断。
   3、如果缓冲区满,新发送的数据不会触发epoll事件(也无异常),每次recv都会为缓冲区腾出空间,只有当缓冲区空闲大小能够再次接收数据epollIN事件可以再次被触发
接收时接收大小为0表示客户端断开(不可能有0数据包触发EPOLLIN),-1表示异常,针对errorno进行判断可以确定是合理异常还是需要终止的异常,>0而不等于缓冲区大小表示单次发送结束。
   4、 如果中途临时调整接收缓存区大小,并且在上一次中数据没有完全接收到用户空间,数据不会丢失,会累加在一起

所以总结起来,系统对于数据的完整性还是做了相当的保正,至于稳定性没有作更深一步的测试

   新增加:
   5、如果主accept监听的soctet fd也设置为非阻塞,那么单纯靠epoll事件来驱动的服务器模型会存在问题,并发压力下发现,每次accept只从系统中取得第一个,所以如果恰冯多个连接同时触发server fd的EPOLLIN事件,在返回的event数组中体现不出来,会出现丢失事件的现象,所以当用ab等工具简单的压载就会发现每次都会有最后几条信息得不到处理,原因就在于此,我现在的解决办法是将server fd的监听去掉,用一个线程阻塞监听,accept成功就处理检测client fd,然后在主线程循环监听client事件,这样epoll在边缘模式下出错的概率就小,测试表明效果明显
6、对于SIG部分信号还是要做屏蔽处理,不然对方socket中断等正常事件都会引起整个服务的退出
7、sendfile(fd, f->SL->sendBuffer.inFd, (off_t *)&f->SL->sendBuffer.offset, size_need);注意sendfile函数的地三个变量是传送地址,偏移量会自动增加,不需要手动再次增加,否则就会出现文件传送丢失现象
8、单线程epoll驱动模型误解:以前我一直认为单线程是无法处理web服务器这样的有严重网络延迟的服务,但nginx等优秀服务器都是机遇事件驱动模型,开始我在些的时候也是担心这些问题,后来测试发现,当client socket设为非阻塞模式的时候,从读取数据到解析http协议,到发送数据均在epoll的驱动下速度非常快,没有必要采用多线程,我的单核cpu(奔三)就可以达到10000page/second,这在公网上是远远无法达到的一个数字(网络延迟更为严重),所以单线程的数据处理能力已经很高了,就不需要多线程了,所不同的是你在架构服务器的时候需要将所有阻塞的部分拆分开来,当epoll通知你可以读取的时候,实际上部分数据已经到了socket缓冲区,你所读取用的事件是将数据从内核空间拷贝到用户空间,同理,写也是一样的,所以epoll重要的地方就是将这两个延时的部分做了类似的异步处理,如果不需要处理更为复杂的业务,那单线程足以满足1000M网卡的最高要求,这才是单线程的意义。
    我以前构建的web服务器就没有理解epoll,采用epoll的边缘触发之后怕事件丢失,或者单线程处理阻塞,所以自己用多线程构建了一个任务调度器,所有收到的事件统统压进任无调度器中,然后多任务处理,我还将read和write分别用两个调度器处理,并打算如果中间需要特殊的耗时的处理就增加一套调度器,用少量线程+epoll的方法来题高性能,后来发现read和write部分调度器是多余的,epoll本来就是一个事件调度器,在后面再次缓存事件分部处理还不如将epoll设为水平模式,所以多此一举,但是这个调度起还是有用处的
   上面讲到如果中间有耗时的工作,比如数据库读写,外部资源请求(文件,socket)等这些操作就不能阻塞在主线程里面,所以我设计的这个任务调度器就有用了,在epoll能处理的事件驱动部分就借用epoll的,中间部分采用模块化的设计,用函数指针达到面相对象语言中的“委托”的作用,就可以满足不同的需要将任务(fd标识)加入调度器,让多线程循环执行,如果中间再次遇到阻塞就会再次加入自定义的阻塞器,检测完成就加入再次存入调度器,这样就可以将多种复杂的任务划分开来,相当于在处理的中间环节在自己购置一个类似于epoll的事件驱动器
    9、多系统兼容:我现在倒是觉得与其构建一个多操作系统都支持的服务器不如构建特定系统的,如果想迁移再次改动,因为一旦兼顾到多个系统的化会大大增加系统的复杂度,并且不能最优性能,每个系统都有自己的独有的优化选项,所以我觉得迁移的工作量远远小于兼顾的工作量
10模块化编程,虽然用c还是要讲求一些模块化的设计的,我现在才发现几乎面相对想的语言所能实现的所有高级特性在c里面几乎都有对应的解决办法(暂时发现除了操作符重载),所有学过高级面相对象的语言的朋友不放把模式用c来实现,也是一种乐趣,便于维护和自己阅读
   11、养成注释的好习惯
分享到:
评论

相关推荐

    linux socket tcp epoll使用教程 例子 源代码

    linux socket tcp epoll使用教程 例子 源代码

    linux socket NIO epoll教程参数讲解.zip

    大并发服务器编程模型 windows iocp完成端口模型可支持1万大并发,但是linux能作到5万大并发

    linux socket tcp大并发 epoll使用教程 有关epoll的一切

    linux socket tcp大并发 epoll使用教程 有关epoll的一切

    socket epoll

    总的来说,Linux Socket配合Epoll模型,为高性能网络服务提供了强大的支持。通过理解和掌握这两个概念,开发者可以设计出更高效、更稳定的网络应用。在学习过程中,可以参考提供的"sock"文件,它可能包含了相关的...

    linux epoll服务器+windows 客户端 socket tcp通信的例子.zip

    - Windows的socket API与Linux类似,但不直接支持epoll。可以使用`select()`或`WSAAsyncSelect()`等方法来实现类似的功能。 - 客户端首先`socket()`创建socket,然后`connect()`到服务器,发送和接收数据。 6. **...

    socket epoll 通讯实例

    socket epoll 通讯实例

    Linux下使用EPoll+队列+多线程的C++实现

    `epoll`是Linux内核提供的一种I/O多路复用技术,它极大地提高了处理大量并发连接的效率。`epoll`的主要优点在于它能显著降低系统调用的开销,因为它通过水平触发和边缘触发两种模式,使得程序只需关注有事件发生的...

    linux c++ epoll网络模型封装类 socket

    封装了epoll功能,很简单的使用epoll,只需要指定epoll服务监听端口,就可以运行epoll服务。可以指定收到数据的回调函数,可以指定有连接的回调函数,可以指定网络关闭的回调函数。自己编写调试epoll模型可能要几天...

    linux下的socket epoll实现

    socket epoll实现。替代原有的select机制,更好的提供网络传输效率。

    linux条件下利用epoll 接收串口数据

    linux系统下,利用epoll接收串口助手发来的数据并打印。

    linux-xia-epoll-socket.rar_epoll_epoll socket_socket_windows soc

    在本资料包中,我们主要探讨`epoll`与`socket`的结合使用,以及如何在Linux环境下构建一个能够支持多用户同时发送请求的服务器。 首先,`epoll`的核心概念是`epoll_create`、`epoll_ctl`和`epoll_wait`三个系统调用...

    linux epoll socket UDP通信的实现! 看清楚不是tcp哟.zip

    本篇文章将深入探讨如何在Linux环境下使用`epoll`与`socket`实现UDP通信。 首先,我们需要了解UDP(User Datagram Protocol)是一种无连接的、不可靠的传输层协议,它的主要特点是速度快、开销小,但不保证数据的...

    linux c epoll服务器windows 客户端通信

    对于Windows Socket客户端,我们使用Windows Socket API(Winsock)来实现与Linux服务器的通信。Winsock遵循Berkeley Sockets接口,因此大部分代码可以与Linux上的C程序兼容。客户端的主要步骤包括: 1. 初始化...

    epoll_高并发socket通讯_

    epoll是Linux内核提供的I/O多路复用技术,它通过事件驱动的方式优化了对大量文件描述符(如socket)的监控。相比于select和poll,epoll有以下优势: 1. **效率**: epoll使用“红黑树”数据结构存储文件描述符,添加...

    linux下通过epoll机制进行串口监听并转发tcp

    Linux下通过epoll机制进行串口监听,当收到数据时,通过tcp进行数据转发给服务器

    linux下Epoll模型实例代码

    在Linux操作系统中,Epoll(Event Poll)是用于高并发I/O处理的一种高效机制,尤其适合于网络服务器的开发。Epoll模型相比传统的select、poll等I/O多路复用模型,具有更好的性能和可扩展性。这个"linux下Epoll模型...

    linux_qq.rar_QQ协议_epoll 文件_linux socket epoll_linux项目_socket好友聊天

    该代码在Linux实现了一个类似于windows上的QQ的聊天工具。主要是基于TCP/IP协议的socket通信。包括服务器端和客户端两部分,其中客户端使用了select的IO多路复用技术,服务器端由于要监听多个客户端,因此使用了...

    Linux网络编程,包括tcp/upd,select/poll/epoll/pdf

    总之,Linux网络编程是一项重要的技能,它涉及到网络通信的基本原理以及多路复用技术的使用,对于开发网络应用程序来说是必不可少的技能。Linux网络编程是指在Linux操作系统上开发网络应用程序的过程。它主要涉及到...

    实战Linux socket编程Linux Socket Programming By Example

    《实战Linux Socket编程》是关于网络编程领域的一本经典书籍,专注于Linux系统下的socket接口使用。这本书通过实例展示了如何在Linux环境下进行网络通信,涵盖了从基础的socket创建、连接到高级的多线程、多进程并发...

    linux 下 通过epoll实现tcp服务器

    在Linux操作系统中,`epoll`是用于I/O多路复用的一种高效机制,尤其适合构建高性能、高并发的网络服务器,例如TCP服务器。本文将详细介绍如何利用`epoll`来实现一个TCP服务器,并结合提供的文件`tcp_epoll_server.c`...

Global site tag (gtag.js) - Google Analytics