winsocket ------- select 模型

套接字select模型,
能够使用winsockets应用程序同时对多个套接字进行管理,调用select()函数,
检查当前套接字的状态,并根据该函数的返回值,判断套接字的可读可写性,然后调用winAPI完成数据的
发送和接收等。
当执行操作套接字满足读写的条件时,需要给应用程序发出通知,应用程序调用相应api函数执行函数
的调用,
int select(
__in     int nfds,  保证与早期的Berkeley套接字程序的兼容
__inout  fd_set *readfds,     具有可读的套接字集合的指针
__inout  fd_set *writefds,    具有可写的套接字集合的指针
__inout  fd_set *exceptfds,   检查错误套接字集合的指针
__in     const struct timeval *timeout  用于设置调用select()函数的等待时间
);
The select function returns the total number of socket handles that are ready and contained in the fd_set structures, 
zero if the time limit expired, or SOCKET_ERROR if an error occurred. If the return value is SOCKET_ERROR, 
WSAGetLastError can be used to retrieve a specific error code. 
conditions for readfds:
The parameter readfds identifies the sockets that are to be checked for readability. If the socket is currently in the listen state, 
it will be marked as readable if an incoming connection request has been received such that an accept is guaranteed to complete without blocking.
For other sockets, readability means that queued data is available for reading such that a call to recv, WSARecv, WSARecvFrom, or recvfrom is guaranteed not to block. 
For connection-oriented sockets, readability can also indicate that a request to close the socket has been received from the peer. 
If the virtual circuit was closed gracefully, and all data was received, then a recv will return immediately with zero bytes read. 
If the virtual circuit was reset, then a recv will complete immediately with an error code such as WSAECONNRESET. 
The presence of OOB data will be checked if the socket option SO_OOBINLINE has been enabled (see setsockopt). 
readfds; 包括以下任何一个条件的套接字:
1.有数据可以读入,此时套接字上调用recv()等输入函数,立即接收对方的数据
2.连接已经关闭,重设和中止
3.假如已经调用listen()函数,而且一个连接正在建立,那么此时调用Accpet()函数已经成功,
conditions for writefds:
The parameter writefds identifies the sockets that are to be checked for writability. If a socket is processing a connect call (nonblocking),
a socket is writeable if the connection establishment successfully completes. If the socket is not processing a connect call, writability means a send, sendto, 
or WSASendto are guaranteed to succeed. However, they can block on a blocking socket if the len parameter exceeds the amount of outgoing system buffer space available.
It is not specified how long these guarantees can be assumed to be valid, particularly in a multithreaded environment. 
writefds: 包括以下任何一个条件的套接字:
1.有数据发出,此时套接字可以调用send()函数,向对方发送数据
2.如果已经在一个非锁定套接字上调用connect()函数,此时连接成功
exceptfds
The parameter exceptfds identifies the sockets that are to be checked for the presence of OOB data or any exceptional error conditions. 
exceptfds 符合任意一个情况
1.如果一个非锁定套接字上调用connect()函数,此时连接失败。
2.有外带的数据或者其他异常错误(OOB data or any exceptional error conditions)可供读取。
confiditon for timeout(const struct timeval *timeout)
timeout 
[in] The maximum time for select to wait, or NULL for blocking operation. 
struct timeval {
long    tv_sec;         /* seconds */
long    tv_usec;        /* and microseconds */
};
This structure is used in the select function. It is taken from the BSD file sys/time.h.
The parameter timeout controls how long the select can take to complete. If timeout is a null pointer, 
select will block indefinitely until at least one descriptor meets the specified criteria. Otherwise, 
timeout points to a TIMEVAL structure that specifies the maximum time that select should wait before returning. 
When select returns, the contents of the TIMEVAL structure are not altered. If TIMEVAL is initialized to {0, 0}, 
select will return immediately; this is used to "poll" the state of the selected sockets. If select returns immediately, 
then the select call is considered nonblocking and the standard assumptions for nonblocking calls apply. For example, 
the blocking hook will not be called, and Windows Sockets will not yield.
调用select()函数,timeout的情况有:
1.空指针, 调用select()函数会无限期等待,当有个套接字能够符合设置条件下,select()就立即返回。
2.0,无论是否有套接字能够符合设置的条件下,select()函数的都会立即的返回,允许应用程序对该select()函数进行轮询,性能方面的考虑。
3.非0值,在非0等待时间有套接字对设置条件满足情况下,select()函数在满足条件是返回,如果在非0时等待时间内,没有套接字满足设置条件,
只要等待时间到,select()函数返回,返回值0。
------宏
Four macros are defined in the header file WINSOCK2.H for manipulating and checking the descriptor sets. 
The variable FD_SETSIZE determines the 【maximum number of descriptors in a set】. (The default value of FD_SETSIZE is 64, 
which can be modified by defining FD_SETSIZE to another value before including WINSOCK2.H.) Internally, 
socket handles in an FD_SET structure are not represented as bit flags as in Berkeley Unix. Their data representation is opaque. 
Use of these macros will maintain software portability between different socket environments. 
The macros to manipulate and check FD_SET contents are: 
FD_CLR(s, *set) // set集合中删除套接字s Removes the descriptor s from set.
FD_ISSET(s, *set)   // Nonzero if s is a member of the set. Otherwise, zero. 
FD_SET(s, *set)     // Adds descriptor s to set. 
FD_ZERO(*set) // Initializes the set to the NULL set
-------调用select()函数中使用宏,完成套接字可读可写的判断
1. 使用FD_ZERO宏,初始化自己感兴趣得套接字集合fd_set, LIKE: FD_ZERO(readfd);
2. 使用FD_SET宏,将套接字分配参与操作的套接字集合fd_set, LIKE: FD_SET(s, readfd);
3. 以该fd_set套接字集合为select()函数参数,等待在指定的fd_set集合中,设置好I/O活动这个套接字,
select()完成后返回在所有的fd_set集合中设置活动好的套接字,并对每个套接字集合进行更新;
4.select()函数成功返回后,使用FD_ISSET宏,对每个fd_set进行检查,LIKE: FD_ISSET(s, readfd), 返回为TRUE,
则该套接字为可读的。
5. 调用window Socket函数对数据进行读取和发送。
-----conditions for use select()
在使用select()函数对套接字进行监控之前,在应用程序中必须将套接字分配给一个集合,设置可读,可写,fd_set结构,然后调用select()进行监控套接字,是否在发送             I/O操作,在调用select()函数readtds,writefds,exceptfds三个参数至少一个不为null,在非空的参数中至少有一个套接字,否则select()函数无套接字等待。
如程序判断某个套接字是否存在可读的数据,操作步骤:
1.将该套接字加入readfds集合;
2.以readfds为参数调用select()函数;
3.当select()函数返回,程序判断该套接字是否还存在readfds套接字集合中;
4.如果该套接字存在readfds集合中,说明该套接字是可读的,程序调用recv()等输入函数获取数据。
---------
The fd_set structure is used by various Windows Sockets functions and service providers, such as the select function,
to place sockets into a "set" for various purposes, such as testing a given socket for readability using the readfds parameter of the select function. 
typedef struct fd_set {   // 管理套接字集合
u_int  fd_count; // 套接字总数
SOCKET fd_array[FD_SETSIZE]; // 套接字数组
} fd_set;
-------优缺点
优势:可以同时对多个建立起来的套接字进行有序的管理,可以阻止应用程序在一次调用I/O时,使用阻塞模式被迫阻塞,使用非阻塞模式,
返回WSAEWOULDBLOCK错误。
缺点:使用select()函数的window程序可能性能上会受损。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值