北京pk赛车,微信pk,北京pk赛车源码

北京pk赛车,微信pk,北京pk赛车源码
地址一:【hubawl.com】狐霸源码论坛
地址二:【bbscherry.com】
前面提到的迭代式服务器与并发服务器都不能从根本上解决大量客户端连接通信的问题,因此为了实现海量客户端连接通信,Linux内核引入了I/O复用模型。分别是select、poll、epoll。
在前面我们分析了通常的I/O模型中,往往限制网络通信效率的就是消息的通知机制和消息的等待过程。
一 函数介绍
select函数原型如下所示:
#include <sys/select.h>
int select(int nfds, fd_set restrict readfds, fd_set restrict writefds, fd_set restrict errorfds, struct timeval restrict timeout);

select成功时返回就绪文件描述符的总数,在超时时间内没有文件描述符就绪则返回0,select失败时返回-1并置errno。

其中,第一个参数为nfds,它指定了待测试的描述符的个数,它的值是待测试的最大描述字加1(这里加1的原因是因为描述符是从0开始的)。
中间3个参数readfds、writefds、errorfds分别指定我们要让内核测试读、写、异常条件的描述符。目前支持的异常条件只有两个:
1:某个套接口的带外数据到达。
2:某个已置为分组方式的伪终端存在可从其主端读取的控制状态信息。
fd_set是一个结构体,用来表示描述符的集合。是一个大小为128B的结构体,因为select最多监控1024个描述符,在fd_set中采用bit-map按位存储原则。
我们定义了如下宏来操作fd_set中的位
#include <sys/select.h>
FD_ZERO(fd_set fd_set);//清除fd_set的所有位
FD_SET(int fd,fd_set
fd_set);//设置fd_set的位fd
FD_CLR(int fd,fd_set fd_set);// 清除fd_set的位fd
Int FD_SET(int fd,fd_set
fd_set);//测试fd_set的位fd是否被正确设置
第五个参数restrict timeout是用来设置select的超时时间,是一个结构体指针
struct timeval
{
long tv_sec; / seconds /
long tv_usec; / microseconds /
}
该参数有以下几种可能:
永远等待下去:仅在有一个描述字准备好I/O时才返回。此时,我们把该参数设置为空指针。
等待一段固定时间:在有一个描述字准备好I/O时返回,但是不超过由该参数所指向的timeval结构中指定的秒数和微秒数。如果超时,返回0.
不等待:检查描述字后立刻返回,这称为轮询(polling)。此时,timeval结构体重的秒数和微秒数都必须设置为0.
二 描述字就绪条件
2.1 套接字准备好读
下列四个条件中的任何一个满足时,一个套接字准备好读:
有数据可读:该套接字接收缓冲区中的字节数大于等于套接字接收缓冲区低潮标记的当前大小。对这样的套接字读操作将不阻塞并返回一个大于0的值(也就是返回准备好读入的数据)。我们可以使用SO_RCVLOWAT套接字选项设置该套接字的低潮标记。对于TCP和UDP套接字而言,其缺省值为1.
关闭连接的读一半:该连接的读这一半关闭(也就是接收了FIN的TCP连接)。对这样的套接字的读操作将不阻塞并返回0(也就是返回EOF)。
给监听套接字准备好新连接:该套接字是一个监听套接字且已完成的连接数不为0.对这样的套接字的accept通常不会阻塞。
待错误处理。其上有一个套接字错误待处理。对这样的套接字的读操作将不阻塞并且返回-1,同时把errno设置成确切的错误条件。这些待处理的无措也可以通过制定SO_ERROR套接口选项调用getsockopt获取并清除。
2.2 套接字准备好写
下列四个条件中的任何一个满足时,一个套接字准备好写:
有可用于写的空间:该套接字发送缓冲区中可用空间字节数大于等于套接字发送缓冲区低潮标记的当前大小,并且或者(i)该套接字已连接,或者(ii)该套接字不需要连接(比如UDP套接字)。这意味着我们把这样的套接字设置成非阻塞,写操作将不阻塞并返回一个正值(例如由传输层接受的字节数)。我们可以使用SO_SNDLOWAT套接字选项来设置该套接字的低潮标记。对于TCP和UDP套接字而言,其缺省值通常为2048.
关闭连接的写一半:该连接的写这一半关闭。对这样的套接字的写操作将产生SIGPIPE信号。
该套接字早先使用非阻塞式connect已建立连接,并且连接已经异步建立,或者connect已经以失败告终。
待处理错误。其上有一个套接字错误待处理。对这样的套接字的写操作将不阻塞并且返回-1,同时把errno设置成确切的错误条件。这些待处理的无措也可以通过制定SO_ERROR套接口选项调用getsockopt获取并清除。
2.3 套接字异常
如果一个套接字存在带外数据或者仍处于带外标记,那么它有异常条件待处理。
接收和发送低潮标记的目的在于:允许应用进程控制在select返回可读或可写条件之前,有多少数据可读或者有多少空间可用于写。比如,如果我们知道除非至少存在64个字节的数据,否则我们的应用进程没有任何有效的工作可以做,那么我们可以把低潮标记设置为64,以防少于64个字节的数据准备好读时,select就唤醒我们。
任何UDP套接字只要其发送低潮标记小于等于发送缓冲区大小(缺省应该总是这种关系)就总是可写的,这是因为UDP套接字不需要连接。
Select有如下缺点值得改进:
1:能够操作的文件描述符是给定的1024个;
2:每监控读、写、异常事件中的任何一个都要在用户态与内核态之间拷贝的数据为128B;
3:在内核中,仍然采用轮询的方式来获取事件就绪的文件描述符。

猜你喜欢

转载自blog.51cto.com/13913747/2156200