select/poll/epoll

linux 内核poll/select/epoll实现剖析 f_ops.poll和wait_queue poll/select/epoll的实现都是基于文件提供的poll方法(f_op->poll),该方法利用poll_table提供的_qproc方法向文件内部事件掩码_key对应的的一个或多个等待队列(wait_queue_head_t)上添加包含唤醒函数(wait_queue_t.func)的节点(wait_queue_t),并检查文件当前就绪... 阅读详情

(1)select==>时间复杂度O(n)

它仅仅知道了,有I/O事件发生了,却并不知道是哪那几个流(可能有一个,多个,甚至全部),我们只能无差别轮询所有流,找出能读出数据,或者写入数据的流,对他们进行操作。所以select具有O(n)的无差别轮询复杂度,同时处理的流越多,无差别轮询时间就越长。

(2)poll==>时间复杂度O(n)

poll本质上和select没有区别,它将用户传入的数组拷贝到内核空间,然后查询每个fd对应的设备状态, 但是它没有最大连接数的限制,原因是它是基于链表来存储的.

(3)epoll==>时间复杂度O(1)

epoll可以理解为event poll,不同于忙轮询和无差别轮询,epoll会把哪个流发生了怎样的I/O事件通知我们。所以我们说epoll实际上是事件驱动(每个事件关联上fd)的,此时我们对这些流的操作都是有意义的。(复杂度降低到了O(1))

select,poll,epoll都是IO多路复用的机制。I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。但select,poll,epoll本质上都是同步I/O,因为他们都需要在读写事件就绪后自己负责进行读写,也就是说这个读写过程是阻塞的,而异步I/O则无需自己负责进行读写,异步I/O的实现会负责把数据从内核拷贝到用户空间。  

epoll跟select都能提供多路I/O复用的解决方案。在现在的Linux内核里有都能够支持,其中epoll是Linux所特有,而select则应该是POSIX所规定,一般操作系统均有实现

select:

select本质上是通过设置或者检查存放fd标志位的数据结构来进行下一步处理。这样所带来的缺点是:

1、 单个进程可监视的fd数量被限制,即能监听端口的大小有限。

      一般来说这个数目和系统内存关系很大,具体数目可以cat /proc/sys/fs/file-max察看。32位机默认是1024个。64位机默认是2048.

2、 对socket进行扫描时是线性扫描,即采用轮询的方法,效率较低:

       当套接字比较多的时候,每次select()都要通过遍历FD_SETSIZE个Socket来完成调度,不管哪个Socket是活跃的,都遍历一遍。这会浪费很多CPU时间。如果能给套接字注册某个回调函数,当他们活跃时,自动完成相关操作,那就避免了轮询,这正是epoll与kqueue做的。

3、需要维护一个用来存放大量fd的数据结构,这样会使得用户空间和内核空间在传递该结构时复制开销大

poll:

poll本质上和select没有区别,它将用户传入的数组拷贝到内核空间,然后查询每个fd对应的设备状态,如果设备就绪则在设备等待队列中加入一项并继续遍历,如果遍历完所有fd后没有发现就绪设备,则挂起当前进程,直到设备就绪或者主动超时,被唤醒后它又要再次遍历fd。这个过程经历了多次无谓的遍历。

它没有最大连接数的限制,原因是它是基于链表来存储的,但是同样有一个缺点:

1、大量的fd的数组被整体复制于用户态和内核地址空间之间,而不管这样的复制是不是有意义。                   

2、poll还有一个特点是“水平触发”,如果报告了fd后,没有被处理,那么下次poll时会再次报告该fd。

epoll:

epoll有EPOLLLT和EPOLLET两种触发模式,LT是默认的模式,ET是“高速”模式。LT模式下,只要这个fd还有数据可读,每次 epoll_wait都会返回它的事件,提醒用户程序去操作,而在ET(边缘触发)模式中,它只会提示一次,直到下次再有数据流入之前都不会再提示了,无 论fd中是否还有数据可读。所以在ET模式下,read一个fd的时候一定要把它的buffer读光,也就是说一直读到read的返回值小于请求值,或者 遇到EAGAIN错误。还有一个特点是,epoll使用“事件”的就绪通知方式,通过epoll_ctl注册fd,一旦该fd就绪,内核就会采用类似callback的回调机制来激活该fd,epoll_wait便可以收到通知。

epoll为什么要有EPOLLET触发模式?

如果采用EPOLLLT模式的话,系统中一旦有大量你不需要读写的就绪文件描述符,它们每次调用epoll_wait都会返回,这样会大大降低处理程序检索自己关心的就绪文件描述符的效率.。而采用EPOLLET这种边沿触发模式的话,当被监控的文件描述符上有可读写事件发生时,epoll_wait()会通知处理程序去读写。如果这次没有把数据全部读写完(如读写缓冲区太小),那么下次调用epoll_wait()时,它不会通知你,也就是它只会通知你一次,直到该文件描述符上出现第二次可读写事件才会通知你!!!这种模式比水平触发效率高,系统不会充斥大量你不关心的就绪文件描述符

epoll的优点:

1、没有最大并发连接的限制,能打开的FD的上限远大于1024(1G的内存上能监听约10万个端口);
2、效率提升,不是轮询的方式,不会随着FD数目的增加效率下降。只有活跃可用的FD才会调用callback函数;
即Epoll最大的优点就在于它只管你“活跃”的连接,而跟连接总数无关,因此在实际的网络环境中,Epoll的效率就会远远高于select和poll。

3、 内存拷贝,利用mmap()文件映射内存加速与内核空间的消息传递;即epoll使用mmap减少复制开销。
select、poll、epoll 区别总结:

1、支持一个进程所能打开的最大连接数

select

单个进程所能打开的最大连接数有FD_SETSIZE宏定义,其大小是32个整数的大小(在32位的机器上,大小就是3232,同理64位机器上FD_SETSIZE为3264),当然我们可以对进行修改,然后重新编译内核,但是性能可能会受到影响,这需要进一步的测试。

poll

poll本质上和select没有区别,但是它没有最大连接数的限制,原因是它是基于链表来存储的

epoll

虽然连接数有上限,但是很大,1G内存的机器上可以打开10万左右的连接,2G内存的机器可以打开20万左右的连接

2、FD剧增后带来的IO效率问题

select

因为每次调用时都会对连接进行线性遍历,所以随着FD的增加会造成遍历速度慢的“线性下降性能问题”。

poll

同上

epoll

因为epoll内核中实现是根据每个fd上的callback函数来实现的,只有活跃的socket才会主动调用callback,所以在活跃socket较少的情况下,使用epoll没有前面两者的线性下降的性能问题,但是所有socket都很活跃的情况下,可能会有性能问题。

3、 消息传递方式

select

内核需要将消息传递到用户空间,都需要内核拷贝动作

poll

同上

epoll

epoll通过内核和用户空间共享一块内存来实现的。

总结:

综上,在选择select,poll,epoll时要根据具体的使用场合以及这三种方式的自身特点。

1、表面上看epoll的性能最好,但是在连接数少并且连接都十分活跃的情况下,select和poll的性能可能比epoll好,毕竟epoll的通知机制需要很多函数回调。

2、select低效是因为每次它都需要轮询。但低效也是相对的,视情况而定,也可通过良好的设计改善 

 

关于这三种IO多路复用的用法,前面三篇总结写的很清楚,并用服务器回射echo程序进行了测试。连接如下所示:

select:IO多路复用之select总结

poll:O多路复用之poll总结

epoll:IO多路复用之epoll总结

  今天对这三种IO多路复用进行对比,参考网上和书上面的资料,整理如下:

1、select实现

select的调用过程如下所示:

(1)使用copy_from_user从用户空间拷贝fd_set到内核空间

(2)注册回调函数__pollwait

(3)遍历所有fd,调用其对应的poll方法(对于socket,这个poll方法是sock_poll,sock_poll根据情况会调用到tcp_poll,udp_poll或者datagram_poll)

(4)以tcp_poll为例,其核心实现就是__pollwait,也就是上面注册的回调函数。

(5)__pollwait的主要工作就是把current(当前进程)挂到设备的等待队列中,不同的设备有不同的等待队列,对于tcp_poll来说,其等待队列是sk->sk_sleep(注意把进程挂到等待队列中并不代表进程已经睡眠了)。在设备收到一条消息(网络设备)或填写完文件数据(磁盘设备)后,会唤醒设备等待队列上睡眠的进程,这时current便被唤醒了。

(6)poll方法返回时会返回一个描述读写操作是否就绪的mask掩码,根据这个mask掩码给fd_set赋值。

(7)如果遍历完所有的fd,还没有返回一个可读写的mask掩码,则会调用schedule_timeout是调用select的进程(也就是current)进入睡眠。当设备驱动发生自身资源可读写后,会唤醒其等待队列上睡眠的进程。如果超过一定的超时时间(schedule_timeout指定),还是没人唤醒,则调用select的进程会重新被唤醒获得CPU,进而重新遍历fd,判断有没有就绪的fd。

(8)把fd_set从内核空间拷贝到用户空间。

总结:

select的几大缺点:

(1)每次调用select,都需要把fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大

(2)同时每次调用select都需要在内核遍历传递进来的所有fd,这个开销在fd很多时也很大

(3)select支持的文件描述符数量太小了,默认是1024

2 poll实现

  poll的实现和select非常相似,只是描述fd集合的方式不同,poll使用pollfd结构而不是select的fd_set结构,其他的都差不多,管理多个描述符也是进行轮询,根据描述符的状态进行处理,但是poll没有最大文件描述符数量的限制。poll和select同样存在一个缺点就是,包含大量文件描述符的数组被整体复制于用户态和内核的地址空间之间,而不论这些文件描述符是否就绪,它的开销随着文件描述符数量的增加而线性增大。

3、epoll

  epoll既然是对select和poll的改进,就应该能避免上述的三个缺点。那epoll都是怎么解决的呢?在此之前,我们先看一下epoll和select和poll的调用接口上的不同,select和poll都只提供了一个函数——select或者poll函数。而epoll提供了三个函数,epoll_create,epoll_ctl和epoll_wait,epoll_create是创建一个epoll句柄;epoll_ctl是注册要监听的事件类型;epoll_wait则是等待事件的产生。

  对于第一个缺点,epoll的解决方案在epoll_ctl函数中。每次注册新的事件到epoll句柄中时(在epoll_ctl中指定EPOLL_CTL_ADD),会把所有的fd拷贝进内核,而不是在epoll_wait的时候重复拷贝。epoll保证了每个fd在整个过程中只会拷贝一次。

  对于第二个缺点,epoll的解决方案不像select或poll一样每次都把current轮流加入fd对应的设备等待队列中,而只在epoll_ctl时把current挂一遍(这一遍必不可少)并为每个fd指定一个回调函数,当设备就绪,唤醒等待队列上的等待者时,就会调用这个回调函数,而这个回调函数会把就绪的fd加入一个就绪链表)。epoll_wait的工作实际上就是在这个就绪链表中查看有没有就绪的fd(利用schedule_timeout()实现睡一会,判断一会的效果,和select实现中的第7步是类似的)。

  对于第三个缺点,epoll没有这个限制,它所支持的FD上限是最大可以打开文件的数目,这个数字一般远大于2048,举个例子,在1GB内存的机器上大约是10万左右,具体数目可以cat /proc/sys/fs/file-max察看,一般来说这个数目和系统内存关系很大。

总结:

(1)select,poll实现需要自己不断轮询所有fd集合,直到设备就绪,期间可能要睡眠和唤醒多次交替。而epoll其实也需要调用epoll_wait不断轮询就绪链表,期间也可能多次睡眠和唤醒交替,但是它是设备就绪时,调用回调函数,把就绪fd放入就绪链表中,并唤醒在epoll_wait中进入睡眠的进程。虽然都要睡眠和交替,但是select和poll在“醒着”的时候要遍历整个fd集合,而epoll在“醒着”的时候只要判断一下就绪链表是否为空就行了,这节省了大量的CPU时间。这就是回调机制带来的性能提升。

(2)select,poll每次调用都要把fd集合从用户态往内核态拷贝一次,并且要把current往设备等待队列中挂一次,而epoll只要一次拷贝,而且把current往等待队列上挂也只挂一次(在epoll_wait的开始,注意这里的等待队列并不是设备等待队列,只是一个epoll内部定义的等待队列)。这也能节省不少的开销。

select/poll/epoll 全对比 本文对比了select、poll和epoll三种I/O多路复用机制。select使用位图方式,存在1024个fd的上限;poll采用数组结构,突破了select的fd限制;epoll通过红黑树和就绪链表实现了高性能事件驱动。在时间复杂度上,select和poll都是O(n),而epoll为O(1)。触发模式方面,select和poll仅支持水平触发,epoll还支持边缘触发。选择建议:少量连接优先考虑select/poll,高并发场景应使用epoll,其中LT模式通用,ET模式适合追求极限性能。epoll是 阅读详情

相关推荐

彻底搞懂 select/poll/epoll,就这篇了!

之前已经把网络 I/O 相关要点都盘了,还剩 select/poll/epoll 这几个区别没说,这篇就来搞搞它们,并且是从完全理解原理的角度来区分它们。本来是要上源码的,但是感觉没啥必要,身为应用开发我觉得理解原理就行了,源码反正看了就忘了,理解才是最重要!所以我就尽量避免代码且用大白话来盘一盘这三个玩意。话不多说,发车。首先,我们知道 select/poll/epoll 是用来实现多路复用的,即一个线程利用它们即可 hold 住多个 socket。按照这个思路,线程不可被任何一个被管理的 Socket

Linuxhus的博客 6437

深入理解select、poll和epoll及区别

问题:如果我们先前创建的几个进程承载不了目前快速发展的业务的话,是不是还得增加进程数?我们都知道系统创建进程是需要消耗大量资源的,所以这样就会导致系统资源不足的情况。 那么有没有一种方式可以让一个进程同时为多个客户端端提供服务? 接下来要讲的IO复用技术就是对于上述问题的最好解答。 对于IO复用,我们可以通过一个例子来很好的理解它。( 例子来自于《TCP/IP网络编程》) 某教室有10名学生和1名老师,这些学生上课会不停的提问,所以一个老师处理不了这么多的问题。那么学校为每个学生都配一名老师,也就

木牛的博客 741

BIO,NIO,AIO的底层(select/poll以及epoll)

分享这篇受益匪浅的好文章

RuiDer的博客 3113

Epoll原理剖析

从事服务端开发,少不了要接触网络编程。epoll 作为 Linux 下高性能网络服务器的必备技术至关重要,nginx、Redis、Skynet 和大部分游戏服务器都使用到这一多路复用技术。 epoll 很重要,但是 epoll 与 select 的区别是什么呢?epoll 高效的原因是什么? 网上虽然也有不少讲解 epoll 的文章,但要么是过于浅显,或者陷入源码解析,很少能有通俗易懂的。笔...

samson 368

【C/C++】select、poll和epoll

在处理并发IO时,我们需要采取适当的IO多路复用技术,以提高程序效率。本文详细探讨了三种主要的IO多路复用技术:select、poll和epoll。首先,我们介绍了select,一种允许进程指示内核等待多个事件中的任何一个发生的函数。然后,我们讨论了poll,这是一种类似于select的函数,但在处理流设备时,它能提供额外的信息。最后,我们探讨了epoll,这是Linux下多路复用I/O接口select/poll的增强版本,它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率。

Ricky的博客 1942

彻底搞懂 select/poll/epoll,就这篇了

之前已经把网络 I/O 相关要点都盘了,还剩 select/poll/epoll 这几个区别没说,这篇就来搞搞它们,并且是从完全理解原理的角度来区分它们。本来是要上源码的,但是感觉没啥必要,身为应用开发者我觉得理解原理就行了,源码反正看了就忘了,理解才是最重要!所以我就尽量避免代码且用大白话来盘一盘这三个玩意。话不多说,发车。首先,我们知道 select/poll/epoll 是用来实现多路复用的,即一个线程利用它们即可 hold 诸多个 socket。按照这个思路,线程不可能被任何一个被管理的 Socke

m0_71777195的博客 1757

select,poll,epoll总结

select的几大缺点:(1)每次调用select,都需要把fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大(2)同时每次调用select都需要在内核遍历传递进来的所有fd,这个开销在fd很多时也很大(3)select支持的文件描述符数量太小了,默认是1024poll的实现和select非常相似,只是描述fd集合的方式不同,poll使用pollfd结构而不是select的fd_set结构,其

dcjhyn的博客 294

I/O 多路复用之select()、poll()、epoll()详解

I/O 多路复用select==>时间复杂度O(n)poll==>时间复杂度O(n)epoll==>时间复杂度O(1)epoll的接口介绍epoll的工作模式epoll和select/poll的对比epoll的优点 select,poll,epoll都是IO多路复用的机制。I/O多路复用就是通过一种机制,一个进程可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作。但select,poll,epoll本质上都是同步I/O,因为他们都需要在读写事件

TABE_的博客 4246

详解select/poll/epoll

特性selectpoll文件描述符上限受FD_SETSIZE(1024)无(仅受系统限制)无(仅受系统限制)用户态拷贝每次调用拷贝整个集合每次调用拷贝整个数组仅epoll_ctl时拷贝就绪检查效率O (n)(遍历整个集合)O (n)(遍历整个数组)O (1)(直接返回就绪列表)触发模式水平触发水平触发水平触发 / 边缘触发跨平台好(Windows/Linux)一般(无 Windows 原生)差(仅 Linux)适用场景低并发、简单场景中等并发高并发(如服务器)

m0_74455373的博客 938

Python爬虫实战:手把手教你用Selenium绕过药监局网站的反爬机制(附完整代码)

本文详细介绍了如何使用Selenium绕过药监局网站的反爬机制,提供了一套完整的Python爬虫实战方案。通过浏览器指纹伪装、动态等待策略、会话维持技巧以及分布式采集设计,帮助开发者高效爬取药监局数据,解决政府类网站常见的反爬挑战。

weixin_42620255的博客 737

基于ST32 DAC7311数模转换器驱动代码及电路设计完整版

基于ST32的DAC7311模数转换器的电路设计及驱动代码完整版

qq_39626643的博客 3718

2.1.1(下)select/poll/epoll

对于我自己本身,这里我有个疑问,为什么在有新连接的时候,新的events事件添加到epoll,直接使用sockfd的ev实例,通过修改ev.data.fd,ev.events,而不创建新的struct epoll_event实例?select/poll/epoll使用场景:当需要高并发的时候,使用epoll,如果并发量不高使用poll,当没法使用poll/epoll时,才使用select。只要io不可读,就会阻塞在select处。在fd为3的io断开后,在此连接,重新分配了fd,值为7,3被系统回收。

2202_75985961的博客 1622

【STM32实战】利用STM32CubeMX配置PWM互补输出驱动电机

本文详细介绍了如何利用STM32CubeMX配置STM32高级定时器的PWM互补输出功能,以驱动电机等需要半桥/全桥电路的应用。通过图形化界面设置定时器参数、使能互补通道并配置关键的死区时间,结合代码示例演示了如何启动PWM输出和动态调整占空比,确保输出安全、精确的互补信号,避免MOS管直通风险,提升驱动可靠性。

weixin_29161785的博客 534

netty select/poll/epoll区别

在Netty框架中,select、poll和epoll是不同操作系统提供的I/O多路复用机制,用于高效管理多个网络连接。它们的核心区别在于事件通知方式和性能表现

qq_40453972的博客 997

告别第三方应用!用Android原生API搭建Miracast投屏接收器

本文深入探讨如何利用Android原生API开发Miracast接收器,绕过第三方依赖,实现高效的屏幕共享。通过Wi-Fi P2P直连、反射调用隐藏API和RTSP会话协商等核心技术,为开发者提供了一套完整的Miracast接收端解决方案,适用于多屏协同场景。

weixin_29174141的博客 385

宽带阻抗匹配的工程实现-第一步,端口驻波仿真

其实阻抗匹配我工作以来经常说,也经常做,但是基本上都是直接在印制板上进行调试。现在想先用仿真软件直接设计出来,才发现很多东西嘴上说容易,想做出来太难了。所以准备写一些文章,记录一下碰到的问题。

pp_0604的博客 2375

关于select/poll/epoll的一切

select用途相比与普通的阻塞IO模型 select相当于是一名监管员 把多个要处理的文件描述符纳入自己的监管 在设定的时间内阻塞查询 看哪些套接字是就绪的 如果是就绪的则对这些套接字...

vjhghjghj的博客 556

YOLOv11知识蒸馏实战:让小模型拥有大模型90%精度,速度提升3倍的终极教程

在self.alpha = alpha # 蒸馏损失权重self.temperature = temperature # 温度系数,控制分布平滑度# 输出分布蒸馏(KL散度损失)# 中间特征蒸馏(MSE损失,对齐中间层特征)# 总蒸馏损失知识蒸馏是YOLOv11在“小模型高性能部署”场景的“破局之法”——它让小模型能“站在大模型的肩膀上”,兼具速度与精度。从损失函数定义到多阶段训练,再到实战落地,本教程已为你铺就了一条清晰的路径。

m0_64661770的博客 800

搞懂 select/poll/epoll,就这篇了

首先,我们知道 select/poll/epoll 是用来实现多路复用的,即一个线程利用它们即可 hold 住多个 socket。 按照这个思路,线程不可别任何一个被管理的 Socket 阻塞,且任一个 Socket 来数据之后都得唤醒线程。 想想看这应该如何实现呢? 我们拿 select 的逻辑来分析下 按照我们的理解,select 管理多个 Socket 的模型如下图所示: 这里要注意一下内核态和用户态的交互,用户程序访问不了内核空间。 所以,我们调用 select 会把所有要管理的 socket

yes 2049

皮肤病识别 - 使用DenseNet或EfficientNet模型在ISIC数据集上进行皮肤病识别任务

在本篇博客中,我们探讨了如何使用 DenseNet 和 EfficientNet 模型在 ISIC 数据集上进行皮肤病识别任务。我们加载了数据集,并进行了预处理。然后我们使用 Keras 构建了两个不同的模型,并训练和评估了它们。最后,我们使用训练好的模型对新的皮肤病图像进行了预测。

斌擎科技 1303

面向可扩展的 ABAP CDS:EXTEND VIEW 全面实战与工程化指引

摘要: 本文深入讲解ABAP CDS的EXTEND VIEW功能,帮助开发者在标准或自建模型上安全扩展字段与关联。核心内容包括: 作用:避免直接修改标准CDS,通过轻量扩展添加业务字段和关联,降低维护风险。 语法要点:需定义CDS扩展实体名和Dictionary Append View名,支持添加普通字段、关联,但不允许聚合或修改原有结构。 限制:不能扩展含聚合、UNION的视图,且扩展字段需避免命名冲突。 工程实践:建议使用客户命名空间,区分结构扩展与元数据扩展,并注意功能性变更需通过其他方式实现。 示例

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 393

I/O复用和select,poll,epoll

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

m0_62494327的博客 1347

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

多路转接 select/poll epoll

poll 解决了 select 的 FD 数量限制问题,但仍然存在 O(N) 遍历的问题。 epoll 通过事件驱动机制,避免遍历所有 FD,提高了 epoll_wait() 的效率,适用于高并发。 epoll 采用 ET 模式,可以减少 epoll_wait() 调用次数,提高吞吐量,但需要开发者正确处理 recv() / send()。

wws7920的博客 825

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

linux中的轮询机制select/poll/epoll

参考:StephenChan's Tech Space http://www.cnblogs.com/xuxm2007/archive/2011/08/15/2139809.html http://xingyunbaijunwei.blog.163.com/blog/static/76538067201241685556302/ 比较   select  sel

paomadi的专栏 1万+

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

上一篇: exec系列函数
下一篇: ioctl
HideInTime
博客等级 码龄9年 86粉丝 131原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值