Unix网络编程学习日记(五):基于epoll与管道的socket客户端

高效使用Linux Socket和Epoll的编程技巧 通过将它们结合起来,可以实现高性能的网络编程。在Linux网络编程中,Socket是一种常用的通信机制,而Epoll则是一种高效的事件驱动I/O模型。在事件循环中,通过epoll_wait函数等待事件的发生,然后根据事件的类型进行相应的处理,可以实现同时处理多个客户端连接和数据传输。Socket是一种用于实现进程间通信的编程接口,通过Socket可以建立客户端和服务器之间的连接,进行数据的收发。通过Socket接收和发送数据,并利用Epoll监听Socket上的事件,实现非阻塞的I/O操作。 阅读详情

这又是一个不成熟的想法。为了尽可能减少对多线程、进程的依赖,减少内存占用,将之前的客户端程序中“发送”和“接收”线程合二为一,尝试使用非阻塞模式socket配合I/O复用实现socket客户端。不过,查阅资料后发现I/O复用更适合用于服务器程序而不是客户端。
其中很重要的一个原因是,使用I/O复用模型时需要对流进行监控,动态调用流对应的处理程序。对于一个简单的客户端程序,动态接收服务器发来的消息很简单,只要监控socket的“读”事件即可。而如何主动触发I/O复用的“写”功能是个问题。以下是《Unix网络编程》中对select函数触发socket“写”事件的条件。

下列四个条件中的任何一个满足时,一个套接字准备好写。
1. 该套接字发送缓冲区中的可用空间字节数大于等于套接字发送缓冲区低水位标记的当前 大小,并且或者该套接字已连接,或者该套接字不需要连接(如UDP套接字)。这意味着如果我 们把这样的套接字设置成非阻寒(第16章),写操作将不阻塞并返回个正值(例如传输层接受的字节数)。我们可以使用SQ_SNDLOWAT套接字选项来设置该套接字的低水位标记。对于TCP 和UDP套接字而言,其默认值通常为2048.
2. 该连接的写半部关闭.对这样的套接字的写操作将产生SIGPIPE信号(5.12节)。
3. 使用非阻塞式connect的套接字已建立连接,或者connect已经以失败告终。 d)其上有一个套接字错误特处理。对这样的套接字的写操作将不阻塞并返回一I(也就是返 回一个错误),同时把errno设置成确切的错误条件。这些待处理的错误也可以通过指定 SQ.ERROR套接字选项调用getsockopt获取并清除

可见,在网络连接正常的情况下,I/O复用模型持续触发“写”事件,难以由程序手动控制。
在Unix网络编程学习日记(四):基于select的单线程半双工socket客户端的实现中,我使用select监控标准输入stdin,即键盘键入数据并按下回车时,select触发stdin的读事件,再在处理事件的过程中将stdin中的数据通过socket发送出去。但是使用这种思路编写的程序难以扩展功能。
后来在网上找到了一个思路,即通过匿名管道作为中间层来手动触发I/O复用模型的“读”事件:http://blog.youkuaiyun.com/aquester/article/details/36627721。虽然局限性也很大,而且徒增了数次内存复制,不过管道总比标准输入流容易控制许多。
想象中的流程大概是这样:
这里写图片描述
但是现实很骨感,由于使用了I/O复用模型需要配合非阻塞socket使用,实际会遇到很多问题。特别是发包速度快时,send函数会抛出EAGAIN错误。所以要考虑到数据的重发。好在epoll有一个边缘触发模式,可以在发送事件(EPOLLOUT)从无效到有效这一过程发生时激活重发功能。为了重发,又需要建立缓存暂存发送失败的数据,而重新发送的时候,又可能遇到发送失败,这时还要考虑多次发送失败的数据与新数据的时序……
这里写图片描述
实际的程序其实远比流程图麻烦,各种循环、判断层层嵌套。同时,由于从磁盘读取数据的速度远快于网络发送速度,缓冲队列常常占用大量内存空间。如果想让生产者/消费者速度匹配,又要涉及到阻塞队列、线程同步等机制了。所以说为何不一开始就用多线程/进程来实现这个客户端程序呢?
《Unix网络编程》中讲解非阻塞式I/O时有这样一句话,对此表示认同:

(socket客户端的)非阻塞版本几乎比select加阻塞式I/O版本快出一倍。fork版本比非阻塞版本稍慢,然而考虑到非阻塞版本代码相比fork版本代码的复杂性,我们推荐简单得多的fork版本。

由此得到了个教训,在写程序之间要尽可能地做好概要设计,防止走弯路。当然,在学习阶段走的这些弯路总带来意外收获。

FIFO配合管道PIPE,实现FIFO传递数据,PIPE触发epoll,异步IO效果 立即下载

相关推荐

别再用默认参数了!手把手教你用2P2Z补偿网络优化Buck电源的动态性能

本文详细介绍了如何通过2P2Z补偿网络优化Buck电源的动态性能,解决默认参数下的负载阶跃响应问题。从频域分析到元件选型,再到实测验证,手把手教你提升相位裕度,显著降低超调量和稳定时间,适用于DCDC和开关电源设计。

weixin_33657398的博客 258

pipe为什么要结合epoll使用

pipe epoll

qq_40648248的博客 967

泛微E9与金蝶云星空单点登录集成实战指南

本文详细介绍了泛微E9与金蝶云星空单点登录(SSO)集成的实战指南,包括前期准备、核心代码实现、常见问题排查及安全加固建议。通过集成,企业可实现一次登录全网通行,显著提升工作效率和安全性。文章特别强调了签名生成机制和跳转URL构造的关键技巧,帮助开发者避免常见错误。

weixin_30689307的博客 535

【用示例学习与理解C++系列】pipe与epoll的使用

一个写线程每隔3秒住管道写一个字符,另一个读线程通道监听epoll事件,从管道读一个字符。 管道的读取端注删事读事件到epoll实例中,当写线程住管道写数据后,读线程可以在事件拉取的循环周期中epoll_wait到可读事件,然后从管道中读出数据

技术的学习与积累是个技术活 1839

libcrypto.so.10(OPENSSL_1.0.2)(64bit) is needed by erlang-22.0.7-1.el7.x86_64

今天安装Rabbitmq的 erlang-22.0.7-1.el7.x86_64.rpmrpm包时遇到了这个坑,害找到说是不容易;错误信息在下面; [root@iz2zef7u84js1qeeq00ewwz RabbitMQ]# rpm -ivh erlang-22.0.7-1.el7.x86_64.rpm warning: erlang-22.0.7-1.el7.x86_64.rpm: Header V4 RSA/SHA1 Signature, key ID 6026dfca: NOKEY error:

qq_45782349的博客 5782

2016域控服务器迁移,WIN Server2016 域服务器迁移出错

各位大神: 这几天刚安装了一台windows server 2016做域迁移时出现错误:1、默认SYSLOG、NETLOGON共享文件重启后自动取消共享,即使手动打开后依然会出现自动取消2、组策略中编辑策略时出现以下报错 policys.png (19.29 KB)2017-2-7 13:52操作此动作之前可以访问本机的共享(NETLOGON)3、使用DCDIAG检测多个报错:C:\Use...

weixin_31833039的博客 3314

Unix/Linux编程:epoll详解

同IO多路复用和信号驱动IO一样,Linux的epoll(event poll) API可以检查多个文件描述符上的IO就绪状态。epoll API的主要优点如下 当检查大量的文件描述符时,epoll的性能扩展性比select和poll高很多 epoll API即支持水平触发也支持边缘触发。与之相反,select()和 poll()只支持水平触发,而信号驱动 I/O 只支持边缘触发 性能表现上,epoll与信号驱动IO类似。但是epoll有一些胜过信号驱动IO的优点 可以避免复杂的信号处理流程(比如信号

OceanStar的博客 2464

嵌入式开发必备:手把手教你用DB-9连接器搞定RS-232串口通信(附万用表测试技巧)

本文详细解析了嵌入式开发中RS-232串口通信的硬件连接核心。从DB-9连接器的引脚定义入手,深入讲解DTE与DCE设备角色,明确直连线与交叉线的选择法则,并重点分享了使用万用表进行线缆连通性测试、电压测量及故障诊断的实战技巧,帮助开发者彻底掌握串口通信的硬件连接与排查方法。

tgb345678的博客 1166

「带着问题看Handler」

重读Handler机制

我有一壶酒,足以慰风尘 2097

Cadence PSpice 仿真6:反向放大器傅里叶仿真(FFT,谐波分析)实战图文教程

总谐波失真(THD)指音频信号源通过功率放大器时,由于非线性元件所引起的输出信号比输入信号多出的额外谐波成分。比如理想运放输出为5V 1Khz的正玄波时,实际输出的信号按照傅里叶展开后不但含有5V 1KHZ的分量,还有1V 2KHZ的分量,那么多出来的1V的分量就是二次谐波,二次谐波失真系数就是20%,由于任意1个波形按照傅里叶展开是可以展开到n次的,所以除了二次谐波外,输出的信号还有3,4,5……n次谐波,随着n的变大谐波的分量会变小,总谐波失真系数就是所有谐波分量和1次谐波(基波)的比值。Cadence

fydar的博客 4956

12、每日卫星任务规划问题的不同公式

本文探讨了卫星任务规划问题的多种数学公式表示方法,包括传统的整数线性规划(ILP)模型、改进的基于路径的公式、基于集合覆盖的公式以及动态规划公式。通过案例研究比较了不同公式的求解效率和适用场景,并提供了使用Python进行实际求解的操作步骤。最后讨论了进一步优化策略及未来研究方向,旨在为解决卫星任务规划问题提供全面的理论支持和实践指导。

assembly8low的博客 204

unix网络编程(三) 两种模式下的epoll服务端

Edge Triggered (ET) 边缘触发只有数据到来才触发,不管缓存区中是否还有数据。Level Triggered (LT) 水平触发只要有数据都会触发。LT模式是默认的工作模式,在这种模式下epoll相当于一个效率较高的poll。

qq_55796594的博客 839

海康DS-7604N-K1/RTB固件包

【摘要】海康DS-7604N-K1/RTB萤石云设备发布V4.30.091版本升级程序(2022.09.19),仅适用于指定型号。升级前需先升级至V3.4.106基础版本,刷机会重置设备为未激活状态,需重新设置admin密码。该机型支持密码/手势登录,无密码时可通过U盘升级。注意事项:升级存在风险,需确认程序适用性;升级过程严禁断电;必须阅读压缩包内的刷机说明。此为定制机型,非必要不建议升级。(150字)

海康威视技术支持 1576

unix网络编程之socket:epoll 系列函数简介、与select、poll 的区别

一、epoll 系列函数简介 #include int epoll_create(int size); int epoll_create1(int flags); int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event); int epoll_wait(int epfd, struct epoll_even

chen 2364

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

管道通信(pipe通信)

管道通信(pipe通信)

m0_47549429的博客 735

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

epoll监听pipe,fork后父进程写给…

这里日志算是一个独立的部分,大可不看,主要是用来记录信息而已,读者可直接用标准输出替换 首先,创建pipe,创建子进程,将pipefd[0](read)加入epoll事件,fork创建父进程,调用write()写入管道,epoll_wait此时便返回结果 #include #include #include #include #include #include #include

Shelsea_x的专栏 2863

I/O复用和select,poll,epoll

select 和 poll 的原理基本相同,就是调用的方式不同。阻塞和非阻塞(超时时间设为0)都能一次系统调用完成监听多个文件描述符。select 、poll 每次系统调用都要重新插入、删除一遍队列,遍历一遍监听的 fds。从原理可以看出 select 和 poll 都是水平触发的(不处理时,文件的就绪状态没有改变)。epoll 在内核里维护了树和队列,文件状态改变时主动回调查询树,插入队列。

m0_62494327的博客 1347

I/O复用的高级应用一:非阻塞connect

I/O复用的高级应用一:非阻塞connect

gxy的博客 261

socket笔记

socket socket是一种ipc方法(介于传输层和应用层的一组api),允许同一主机或网络连接的主机上的应用程序交换数据。 现代操作系统支持下列socket: AF_UNIX: 允许同一主机的应用程序进行通信。AF_INET: 允许通过ipv4连接的主机的应用程序进行通信。AF_INET6: 允许通过ipv6连接的主机的应用程序进行通信。AF:地址族(address family)

u012662731的博客 3705

五分钟帮您理解Linux网络核心知识点——socket和epoll

关于linux网络相关的基础知识点,最热的两个就是socket和epoll,接下来我就用最简单的方式把他俩说清楚便于大家理解!

liwenxiang629的博客 1159

linux C++监听管道文件方式

非阻塞打开文件,用read循环定时读取,性能不好。

qq_42145185的博客 630

epoll+管道的测试

epoll+管道的测试

364

Pipes、FIFOs和UNIX Domain Sockets

Pipes是如何分类的? ordinary pipes and named pipes. Ordinary pipes on Windows systems are termed anonymous pipes 为什么叫匿名管道与命名管道? FIFOs表示什么含义? Pipes、FIFOs和UNIX Domain Sockets找到对端进程,实现进程间通信的关键过程是什么? ordinary pipes: Typically, a parent process creates a pipe an.

qq_22948593的博客 947

unix网络编程之从selelct谈到epoll

unix网络编程之从selelct谈到epoll 第一部分: I/O复用:select和poll函数 如果一个或多个I/O条件满足(例如,输入已准备好被读,或者描述字可以承接更多的输出)时,我们就被通知到。这个能力被称为I/O复用,是由函数select和poll支持的。   先介绍一下各种I/O模型: 阻塞I/O,非阻塞I/O,I/O复用,信号驱动I/O(SIGIO),异步I/O

田原的学习笔记 2493

linux socket 错误处理,linux非阻塞的socket EAGAIN的错误处理【转】

版权声明:本文为博主原创文章,未经博主允许不得转载。在Linux中使用非阻塞的socket的情形下。(一)发送时当客户通过Socket提供的send函数发送大的数据包时,就可能返回一个EAGAIN的错误。该错误产生的原因是由于send 函数中的size变量大小超过了tcp_sendspace的值。tcp_sendspace定义了应用在调用send之前能够在kernel中缓存的数据量。当应用程序在s...

weixin_39932181的博客 450
上一篇: Linux进程与线程的比较
下一篇: 基于pthread的C++阻塞队列模板类的实现
Azure小诶
博客等级 码龄15年 18粉丝 18原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值