- 浏览: 1019822 次
- 性别:
- 来自: 杭州
文章分类
- 全部博客 (826)
- 硬件 (8)
- 软件 (24)
- 软件工程 (34)
- JAVA (229)
- C/C++/C# (77)
- JavaScript (8)
- PHP (1)
- Ruby (3)
- MySQL (14)
- 数据库 (19)
- 心情记事 (12)
- 团队管理 (19)
- Hadoop (1)
- spring (22)
- mybatis(ibatis) (7)
- tomcat (16)
- velocity (0)
- 系统架构 (6)
- JMX (8)
- proxool (1)
- 开发工具 (16)
- python (10)
- JVM (27)
- servlet (5)
- JMS (26)
- ant (2)
- 设计模式 (5)
- 智力题 (2)
- 面试题收集 (1)
- 孙子兵法 (16)
- 测试 (1)
- 数据结构 (7)
- 算法 (22)
- Android (11)
- 汽车驾驶 (1)
- lucene (1)
- memcache (12)
- 技术架构 (7)
- OTP-Erlang (7)
- memcached (17)
- redis (20)
- 浏览器插件 (3)
- sqlite (3)
- Heritrix (9)
- Java线程 (1)
- scala (0)
- Mina (6)
- 汇编 (2)
- Netty (15)
- libevent (0)
- CentOS (12)
- mongod (5)
- mac os (0)
最新评论
-
kingasdfg:
你这里面存在一个错误添加多个任务 应该是这样的 /** * ...
Quartz的任务的临时启动和暂停和恢复【转】 -
kyzeng:
纠正一个错误,long型对应的符号是J,不是L。
Jni中C++和Java的参数传递 -
zhaohaolin:
抱歉,兄弟,只是留下作记录,方便学习,如果觉得资料不好,可以到 ...
netty的个人使用心得【转】 -
cccoooccooco:
谢谢!自己一直以为虚机得使用网线才可以与主机连接呢。。
主机网卡无网线连接与虚拟机通信 -
yuqilin001:
要转别人的东西,请转清楚点嘛,少了这么多类,误人子弟
netty的个人使用心得【转】
转自:http://blog.chinaunix.net/u/12335/showart.php?id=158367
(现在还是一知半解,瞎搞,呵呵~~~~~~~)
摘录其中一段,用于做 linux的COM.
可能用到的.h
#include <sys/select.h>
还有 有用的命令 man select
:)
介绍一个函数select
int select(int nfds,fd_set *readfds,fd_set *writefds,
fd_set *except fds,struct timeval *timeout)
void FD_SET(int fd,fd_set *fdset)
void FD_CLR(int fd,fd_set *fdset)
void FD_ZERO(fd_set *fdset)
int FD_ISSET(int fd,fd_set *fdset)
一般的来说当我们在向文件读写时,进程有可能在读写出阻塞,直到一定的条件满足. 比如我们从一个套接字读数据时,可能缓冲区里面没有数据可读 (通信的对方还没有 发送数据过来),这个时候我们的读调用就会等待(阻塞)直到有数据可读.如果我们不 希望阻塞,我们的一个选择是用select系统 调用. 只要我们设置好select的各个参数,那么当文件可以读写的时候select回"通知"我们 说可以读写了. readfds所有要读的文件文 件描述符的集合
writefds所有要的写文件文件描述符的集合
exceptfds其他的服要向我们通知的文件描述符
timeout超时设置.
nfds所有我们监控的文件描述符中最大的那一个加1
在我们调用select时进程会一直阻塞直到以下的一种情况发生. 1)有文件可以读.2)有文件可以写.3)超时所设置的时间到.
为了设置文件描述符我们要使用几个宏. FD_SET将fd加入到fdset
FD_CLR将fd从fdset里面清除
FD_ZERO从fdset中清除所有的文件描述符
FD_ISSET判断fd是否在fdset集合中
使用select的一个例子
int use_select(int *readfd,int n)
{
fd_set my_readfd;
int maxfd;
int i;
maxfd=readfd[0];
for(i=1;i
if(readfd[i]>maxfd) maxfd=readfd[i];
while(1)
{
/* 将所有的文件描述符加入 */
FD_ZERO(&my_readfd);
for(i=0;i
FD_SET(readfd[i],*my_readfd);
/* 进程阻塞 */
select(maxfd+1,& my_readfd,NULL,NULL,NULL);
/* 有东西可以读了 */
for(i=0;i
if(FD_ISSET(readfd[i],&my_readfd))
{
/* 原来是我可以读了 */
we_read(readfd[i]);
}
}
}
使用select后我们的服务器程序就变成了.
初始话(socket,bind,listen);
while(1)
{
设置监听读写文件描述符(FD_*);
调用select;
如果是倾听套接字就绪,说明一个新的连接请求建立
{
建立连接(accept);
加入到监听文件描述符中去;
}
否则说明是一个已经连接过的描述符
{
进行操作(read或者write);
}
}
用过 WinSock API 网友们知道:WinSock 编程中有一很方便的地方便是其
息驱动机制,不管是底层 API 的 WSAAsyncSelect() 还是 MFC 的异步Socket类:
CAsyncSocket,都提供了诸如 FD_ACCEPT、FD_READ、FD_CLOSE 之类的消息
供编程人员捕捉并处理。FD_ACCEPT 通知进程有客户方Socket请求连接,
FD_READ通知进程本地Socket有东东可读,FD_CLOSE通知进程对方Socket已
关闭。那么,BSD Socket 是不是真的相形见拙呢?
非也! 'cause cpu love unix so.
BSD UNIX中有一系统调用芳名select()完全可以提供类似的消息驱动机制。
cpu郑重宣布:WinSock的WSAAsyncSeclet()不过是此select()的fork版!
bill也是fork出来的嘛,xixi.
select()的机制中提供一fd_set的数据结构,实际上是一long类型的数组,
每一个数组元素都能与一打开的文件句柄(不管是Socket句柄,还是其他
文件或命名管道或设备句柄)建立联系,建立联系的工作由程序员完成,
当调用select()时,由内核根据IO状态修改fd_set的内容,由此来通知执
行了select()的进程哪一Socket或文件可读,下面具体解释:
#include
#include
#include
int select(nfds, readfds, writefds, exceptfds, timeout)
int nfds;
fd_set *readfds, *writefds, *exceptfds;
struct timeval *timeout;
ndfs:select监视的文件句柄数,视进程中打开的文件数而定,一般设为呢要监视各文件
中的最大文件号加一。
readfds:select监视的可读文件句柄集合。
writefds: select监视的可写文件句柄集合。
exceptfds:select监视的异常文件句柄集合。
timeout:本次select()的超时结束时间。(见/usr/sys/select.h,
可精确至百万分之一秒!)
当readfds或writefds中映象的文件可读或可写或超时,本次select()
就结束返回。程序员利用一组系统提供的宏在select()结束时便可判
断哪一文件可读或可写。对Socket编程特别有用的就是readfds。
几只相关的宏解释如下:
FD_ZERO(fd_set *fdset):清空fdset与所有文件句柄的联系。
FD_SET(int fd, fd_set *fdset):建立文件句柄fd与fdset的联系。
FD_CLR(int fd, fd_set *fdset):清除文件句柄fd与fdset的联系。
FD_ISSET(int fd, fdset *fdset):检查fdset联系的文件句柄fd是否
可读写,>0表示可读写。
(关于fd_set及相关宏的定义见/usr/include/sys/types.h)
这样,你的socket只需在有东东读的时候才读入,大致如下:
...
int sockfd;
fd_set fdR;
struct timeval timeout = ..;
...
for(;;) {
FD_ZERO(&fdR);
FD_SET(sockfd, &fdR);
switch (select(sockfd + 1, &fdR, NULL, &timeout)) {
case -1:
error handled by u;
case 0:
timeout hanled by u;
default:
if (FD_ISSET(sockfd)) {
now u read or recv something;
/* if sockfd is father and
server socket, u can now
accept() */
}
}
}
所以一个FD_ISSET(sockfd)就相当通知了sockfd可读。
至于struct timeval在此的功能,请man select。不同的timeval设置
使使select()表现出超时结束、无超时阻塞和轮询三种特性。由于
timeval可精确至百万分之一秒,所以Windows的SetTimer()根本不算
什么。你可以用select()做一个超级时钟。
FD_ACCEPT的实现?依然如上,因为客户方socket请求连接时,会发送
连接请求报文,此时select()当然会结束,FD_ISSET(sockfd)当然大
于零,因为有报文可读嘛!至于这方面的应用,主要在于服务方的父
Socket,你若不喜欢主动accept(),可改为如上机制来accept()。
至于FD_CLOSE的实现及处理,颇费了一堆cpu处理时间,未完待续。
--
讨论关于利用select()检测对方Socket关闭的问题:
仍然是本地Socket有东东可读,因为对方Socket关闭时,会发一个关闭连接
通知报文,会马上被select()检测到的。关于TCP的连接(三次握手)和关
闭(二次握手)机制,敬请参考有关TCP/IP的书籍。
不知是什么原因,UNIX好象没有提供通知进程关于Socket或Pipe对方关闭的
信号,也可能是cpu所知有限。总之,当对方关闭,一执行recv()或read(),
马上回返回-1,此时全局变量errno的值是115,相应的sys_errlist[errno]
为"Connect refused"(请参考/usr/include/sys/errno.h)。所以,在上
篇的for(;;)...select()程序块中,当有东西可读时,一定要检查recv()或
read()的返回值,返回-1时要作出关断本地Socket的处理,否则select()会
一直认为有东西读,其结果曾几令cpu伤心欲断针脚。不信你可以试试:不检
查recv()返回结果,且将收到的东东(实际没收到)写至标准输出...
在有名管道的编程中也有类似问题出现。具体处理详见拙作:发布一个有用
的Socket客户方原码。
至于主动写Socket时对方突然关闭的处理则可以简单地捕捉信号SIGPIPE并作
出相应关断本地Socket等等的处理。SIGPIPE的解释是:写入无读者方的管道。
在此不作赘述,请详man signal。
以上是cpu在作tcp/ip数据传输实验积累的经验,若有错漏,请狂炮击之。
唉,昨天在hacker区被一帮孙子轰得差点儿没短路。ren cpu(奔腾的心) z80
补充关于select在异步(非阻塞)connect中的应用,刚开始搞socket编程的时候
我一直都用阻塞式的connect,非阻塞connect的问题是由于当时搞proxy scan
而提出的呵呵
通过在网上与网友们的交流及查找相关FAQ,总算知道了怎么解决这一问题.同样
用select可以很好地解决这一问题.大致过程是这样的:
1.将打开的socket设为非阻塞的,可以用fcntl(socket, F_SETFL, O_NDELAY)完
成(有的系统用FNEDLAY也可).
2.发connect调用,这时返回-1,但是errno被设为EINPROGRESS,意即connect仍旧
在进行还没有完成.
3.将打开的socket设进被监视的可写(注意不是可读)文件集合用select进行监视,
如果可写,用
getsockopt(socket, SOL_SOCKET, SO_ERROR, &error, sizeof(int));
来得到error的值,如果为零,则connect成功.
在许多unix版本的proxyscan程序你都可以看到类似的过程,另外在solaris精华
区->编程技巧中有一个通用的带超时参数的connect模块.
发表评论
-
NotePad++ - 安装和配置C/C++开发插件
2011-11-15 23:00 1854NotePad++ - 安装和配置C/C+ ... -
VC中使用ATL编写控件 【转】
2011-10-21 15:23 2149VC中使用ATL编写控件 作者:邵盛松 2010 ... -
在Windows环境下MongoDB搭建和简单操作【转】
2011-10-21 12:37 1001一,安装mongoDB 1,解 ... -
Mongodb在Windows下安装及配置【转】
2011-10-21 12:35 5921.下载mongodb的windows版本,有32位和64位版 ... -
一篇介绍VC开发OCX的文章[转]
2011-10-20 17:57 1937转自“http://www.cnblogs.com/genga ... -
使你的ActiveX控件执行时不弹出安全性提示 (转载)
2011-10-20 17:56 1220使你的ActiveX控件执行时不弹出安全性提示 2010-0 ... -
VC++ 的MFC 和ATL 及COM 是什么?
2011-10-20 01:12 1027一、什么是MFC 微软基础类(Micro ... -
使用ATL编写一个简单的COM服务器【转】
2011-10-20 01:10 903下载例子代码 本文的对象是COM编程 ... -
使用VC++6.0制作ASP服务器控件简介[转]
2011-10-20 01:10 710用ASP写网页的程序 员,一定对VBSript语句“Set ... -
基于CentOS 5.4搭建nginx+php+spawn-fcgi+mysql
2011-09-01 13:49 1584基于CentOS 5.4搭建nginx+php+sp ... -
解决mrtg的Use of uninitialized value in hash element at /usr/bin/indexmaker line 35
2011-09-01 13:41 2345mrtg的安装过程这里就不再阐述,随便搜索一下。使用ind ... -
用MRTG检测Linux网络性能
2011-09-01 10:49 924随着Linux应用的日益广泛,有大量的网络服务器使用Linux ... -
Linux安装配置maven3.0以及搭建nexus私服
2011-08-30 23:45 1681一、软件准备 1、apache-maven-3.0-b ... -
GraphicsMagick介绍及安装
2011-08-30 23:16 1567作者:Cocowool 来源:博客园 发布时 ... -
Makefile
2011-08-30 22:10 904CC = g++ CFLAG = -Wall -g -w ... -
高位字节优先 低位字节优先
2011-08-24 17:30 1227自第一台计算机诞生, ... -
C++方式的文件操作
2011-08-24 16:05 1856本文主要讨论C++标准I/O库,主要内容为控制台输入输出流 ... -
【JAVA实用工具】JNA-通过它调用C++的方法,比JNI方便很多访问网站需要代理,所以把它COPY出来备忘
2011-08-24 00:33 3226How To Get Started Using JN ... -
Jni中C++和Java的参数传递
2011-08-24 00:04 5168如何使用JNI的一些基本方法和过程在网上多如牛毛,如果你对 ... -
aaaaa
2011-08-24 00:04 1039如何使用JNI的一些基本方法和过程在网上多如牛毛,如果你对 ...
相关推荐
利用select函数在linux环境下实现的一个聊天程序,满足要求: (1)用户默认出于广播模式,一个客户在其客户端发送消息,其他客户端用户全部都可以收到; (2)程序支持下列命令 /help:显示帮助信息 /quit:用户退出...
select函数详解
在Linux系统中,`select`函数是用于网络编程中处理多路I/O复用的关键机制之一,它允许程序同时监控多个文件描述符(如网络套接字)的状态变化,而无需实际读取或写入数据。`select`函数在处理高并发连接请求时尤其...
在Linux系统中,`select`函数是用于处理多个文件描述符(FD)的I/O事件的一种方式,尤其在多路复用I/O编程中扮演着重要角色。它允许程序同时监控多个文件描述符,等待它们准备就绪后进行读写操作,而无需轮询检查每...
select 和 poll 函数都是 Linux 中常用的系统调用,它们用于查询设备是否可读写或是否处于某种状态。在设备驱动程序中,select 和 poll 函数可以用于查询设备的状态,从而实现设备的异步输入/输出操作。
### Linux系统中的Select函数详解 #### 一、引言 在Linux系统中,`select()`函数作为处理I/O多路复用的一种经典方法,在网络编程领域占有重要地位。特别是对于那些需要同时处理多个连接的应用场景来说,使用`select...
### Linux C语言中的select函数详解 #### 一、select函数简介 `select`函数是Linux系统下用于实现I/O多路复用的核心函数之一,在C语言编程中被广泛使用。它能够有效地监控多个文件描述符(File Descriptor, FD),...
在这个“UART1.rar_Uart1Sends_linux_select_uart select函数”压缩包中,我们关注的是如何利用select函数来实现UART1的发送和接收功能。下面将详细介绍这个主题。 UART1是嵌入式系统或开发板上常见的硬件接口,...
利用select函数,实现了从terminal端输入数据,然后输出到指定的文件中,适合新手,如果有什么问题,欢迎在下面评论。
epoll在内核版本2.6以上才出现的新的函数,而他们在linux内核中的实现都是十分相似。 这三种函数都需要设备驱动提供poll回调函数,对于套接字而言,他们是 tcp_poll,udp_poll和datagram_poll; 对于自己开发的设备...
在Linux系统中,`select`函数是一个非常重要的I/O多路复用机制,它允许一个进程监视多个文件描述符(包括串口),等待数据就绪后再进行读写操作。在这个场景下,`select`被用来处理串口通信,特别是在嵌入式Linux...
首先,`select`函数是Linux系统调用之一,它的主要作用是监控一组文件描述符,等待它们变为可读、可写或出现错误状态。这使得开发者可以构建高效的并发服务器,避免了因轮询每个连接而浪费的CPU资源。在描述中的简单...
在Linux系统中,`select`函数的实现与底层驱动程序紧密相关。驱动程序需要实现特定的接口——`fops`结构体中的`poll`函数。当`select`函数调用时,会遍历各个文件描述符,并调用对应的`poll`函数来获取文件描述符的...
在Linux操作系统中,`select`函数是用于处理多个文件描述符(FDs)的I/O事件,它允许程序在一个或多个文件描述符准备就绪时得到通知。在本例中,我们将利用`select`来创建一个简单的命令行计算器程序,用户可以输入...
linux中select()函数分析.pdf
在Linux系统编程中,`select`函数是一种常用的I/O多路复用机制,它允许程序同时监控多个文件描述符(包括标准输入、输出、错误,以及打开的文件、网络套接字等)的状态,等待它们就绪后再进行处理。本资料主要介绍了...
为了解决这一问题,Linux系统提供了`select`函数,它是一种非阻塞式的I/O多路复用技术,能够高效地处理多个文件描述符的读写操作。本篇文章将深入探讨`select`函数的工作原理、使用方法以及其在实际应用中的示例。 ...
在Linux系统编程中,`select`函数是一种常用的I/O多路复用技术,它允许程序同时监控多个文件描述符(file descriptors),等待其中任意一个或多个准备好读写操作。这个功能对于编写高并发、非阻塞的服务器端程序至关...
在Linux操作系统中,`select`函数是用于处理多个文件描述符(FD)就绪状态监控的一种方式,尤其在实现并发服务器时,它扮演了关键角色。`select`模型允许程序在一个时间点监视多个输入源,当其中任何一个源准备好...
### Linux中的Select技术详解 #### 一、Select技术概述 Select技术是一种用于多路复用I/O输入输出的模式,在Linux环境下广泛应用于网络编程中。它通过轮询机制来检测一组套接字(socket)的状态变化,从而实现对多...