织梦CMS - 轻松建站从此开始!

罗索

Proxy源代码分析--谈谈如何学习linux网络编程(3)

jackyhwei 发布于 2010-10-19 11:21 点击:次 
如果timeout-tv_sec!=0||timeout-tv_usec!=0,那么这两个参数的值即为我们希望函数等待的时 间。其中tv_sec设置时间单位为秒,tv_usec设置时间单位为微秒。如果
TAG:


如果timeout->tv_sec!=0||timeout->tv_usec!=0,那么这两个参数的值即为我们希望函数等待的时 间。其中tv_sec设置时间单位为秒,tv_usec设置时间单位为微秒。如果在超时的时候,在我们指定的所有文件描述符里面仍然没有任何一个准备好的 话,则select()将返回"0"。
中间三个参数的数据类型是fd_set,它的意思是文件描述符集,而readfds, writefds和exceptfds则分别是指向文件描述符集的指针,他们分别描述了我们所关心的可读、可写以及状态异常的各个文件描述符。之所以我们 称select()可以创建一个文件描述符"表",那个所谓的表就是由这三个参数指向的数据结构组成的。其具体结构如图1所示。其中在每个set_fd数 据类型中都为我们关心的所有文件描述符保留了一位。所以在监测文件描述符状态的时候,就在这些set_fd数据结构中查询相关的位。
第一个参数n用来说明到底需要遍历多少个描述符位。n的值一般是这样设置的,从我们关心的所有文件描述符中选出最大值再加1。例如我们设置的所有文件 描述符中最大的为6,那么将n设置为7,则系统在检测描述符状态的时候,就只用遍历前7位(fd0~fd6)的状态。不过如果不想这样麻烦的话,我们可以 象例程中那样将n的值直接设置为FD_SETSIZE。这是系统中设定的最大文件描述符个数,不同的系统这个值也不相同,一般是256或是1024。这样 在检测描述符状态的时候,函数将遍历所有的描述符位。
在调用select()函数实现多路I/O转接时,首先我们要声明一个新的文件描述符集,就象例程中这样:
fd_set rdfdset;
然后调用FD_ZERO()清空此文件描述符集的所有位,以免下面检测描述符位的时候返回错误结果:
FD_ZERO(&rdfdset);
然后调用FD_SET()在文件描述符集中设置我们关心的位。在本例中,我们关心的就是分别与用户主机和远端主机连接的两个套接字描述符,所以执行这样的语句:
FD_SET(usersockfd,&rdfdset);
FD_SET(isosockfd,&rdfdset);
然后调用select()返回描述符状态,此时描述符状态被存储进描述符集,也就是set_fd数据结构中。在图1中我们看到所有的描述符位状态都是 "0",在select()返回后,例如fd0可读,则在readfds描述符集中fd0对应的位上将状态标志设置为"1",如果fd1可写,则 writefds描述符集中fd1对应的位上将状态标志设置为"1",状态异常的情况也也与此相同。在本例中,我们只关心两个套接字描述符是否可写,因此 执行这样的select()函数:
select(FD_SETSIZE,&rdfdset,NULL,NULL,NULL)
那么在select()返回后怎样检测set_fd数据结构中描述符位的状态呢?这就要调用函数FD_ISSET(),如果对应文件描述符的状态为"已准备好"(即描述符位为"1"),则FD_ISSET()返回"1",否则返回"0"。
-----------------------------------------------------------------
if (FD_ISSET(usersockfd,&rdfdset)) {
if ((iolen = read(usersockfd,buf,sizeof(buf))) <= 0)
break; /* zero length means the host disconnected */
write(isosockfd,buf,iolen);
-----------------------------------------------------------------
这一段代码就实现从套接字usersockfd(用户主机)到套接字isosockfd(远端主机)的无阻塞传输。而下一段代码实现反方向的无阻塞传输:
-----------------------------------------------------------------
if (FD_ISSET(isosockfd,&rdfdset)) {
if ((iolen = read(isosockfd,buf,sizeof(buf))) <= 0)
break; /* zero length means the host disconnected */
write(usersockfd,buf,iolen);
-----------------------------------------------------------------
这样就通过proxy实现了用户主机与远端主机之间的通信。
对这段proxy代码我只是写了一些自己的理解,大多数是一些函数的用法,这些都是linux网络编程中一些最基础的知识,如果有不对的地方,还请各位大虾批评指正。

(qipnx)
本站文章除注明转载外,均为本站原创或编译欢迎任何形式的转载,但请务必注明出处,尊重他人劳动,同学习共成长。转载请注明:文章转载自:罗索实验室 [http://www.rosoo.net/a/201010/10335.html]
本文出处:CSDN博客 作者:qipnx
顶一下
(0)
0%
踩一下
(0)
0%
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
用户名: 验证码:点击我更换图片
栏目列表
将本文分享到微信
织梦二维码生成器
推荐内容