Live555中的Select

源:http://www.cnblogs.com/netivs/archive/2012/02/25/2367616.html


Live555的关键函数是void BasicTaskScheduler::SingleStep(unsigned maxDelayTime),就是这个函数不停的循环执行才驱动了整个Live555的运行。因此,阅读和分析Live555的原理,关键之一就是要搞懂这个函数。 SingleStep中使用了select这种网络编程I/O模式来实现对多个网络套接字的管理。因此,我们有必要搞清楚win32下的select编程的相关知识。

       Windows下的网络编程,首推的参考书籍当之无愧的肯定是《Network Programming for Microsoft Windows》第二版,下面是书中对select的介绍:

       

The select Model

The select model is another I/O model widely available in Winsock. We call it the select model because it centers on using the select function to manage I/O. The design of this model originated on UNIX-based computers featuring Berkeley socket implementations. The select model was incorporated into Winsock 1.1 to allow applications that want to avoid blocking on socket calls the capability to manage multiple sockets in an organized manner. Because Winsock 1.1 is backward-compatible with Berkeley socket implementations, a Berkeley socket application that uses the select function should technically be able to run without modification.

The select function can be used to determine if there is data on a socket and if a socket can be written to. The reason for having this function is to prevent your application from blocking on an I/O bound call such as send or recv when a socket is in a blocking mode and to prevent the WSAEWOULDBLOCK error when a socket is in a non-blocking mode. The select function blocks for I/O operations until the conditions specified as parameters are met. The function prototype for select is as follows:

int select(
    int nfds,
    fd_set FAR * readfds,
    fd_set FAR * writefds,
    fd_set FAR * exceptfds,
    const struct timeval FAR * timeout
);

The first parameter, nfds, is ignored and is included only for compatibility with Berkeley socket applications. You'll notice that there are three fd_set parameters: one for checking readability (readfds), one for writeability (writefds), and one for out-of-band data (exceptfds). Essentially, the fd_set data type represents a collection of sockets. The readfds set identifies sockets that meet one of the following conditions:

  • Data is available for reading.

  • Connection has been closed, reset, or terminated.

  • If listen has been called and a connection is pending, the accept function will succeed.

The writefds set identifies sockets in which one of the following is true:

  • Data can be sent.

  • If a non-blocking connect call is being processed, the connection has succeeded.

Finally, the exceptfds set identifies sockets in which one of the following is true:

  • If a non-blocking connect call is being processed, the connection attempt failed.

  • OOB data is available for reading.

For example, when you want to test a socket for readability, you must add it to the readfds set and wait for the select function to complete. When the select call completes, you have to determine if your socket is still part of the readfds set. If so, the socket is readable—you can begin to retrieve data from it. Any two of the three parameters (readfdswritefdsexceptfds) can be null values (at least one must not be null), and any non-null set must contain at least one socket handle; otherwise, the select function won't have anything to wait for. The final parameter, timeout, is a pointer to a timeval structure that determines how long the select function will wait for I/O to complete. Iftimeout is a null pointer, select will block indefinitely until at least one descriptor meets the specified criteria. The timeval structure is defined as

struct timeval 
{
    long tv_sec; 
    long tv_usec;
};

The tv_sec field indicates how long to wait in seconds; the tv_usec field indicates how long to wait in milliseconds. The timeout value {0, 0} indicates select will return immediately, allowing an application to poll on the select operation. This should be avoided for performance reasons. When select completes successfully, it returns the total number of socket handles that have I/O operations pending in the fd_setstructures. If the timeval limit expires, it returns 0. If select fails for any reason, it returns SOCKET_ERROR.

Before you can begin to use select to monitor sockets, your application has to set up either one or all of the read, write, and exceptionfd_set structures by assigning socket handles to a set. When you assign a socket to one of the sets, you are asking select to let you know if the I/O activities just described have occurred on a socket. Winsock provides the following set of macros to manipulate and check thefd_set sets for I/O activity.

  • FD_ZERO(*set) Initializes set to the empty set. A set should always be cleared before using.

  • FD_CLR(s, *set) Removes socket s from set.

  • FD_ISSET(s, *set) Checks to see if s is a member of set and returns TRUE if so.

  • FD_SET(s, *set) Adds socket s to set.

For example, if you want to find out when it is safe to read data from a socket without blocking, simply assign your socket to the fd_readset using the FD_SET macro and then call select. To test whether your socket is still part of the fd_read set, use the FD_ISSET macro. The following five steps describe the basic flow of an application that uses select with one or more socket handles:

  1. Initialize each fd_set of interest by using the FD_ZERO macro.

  2. Assign socket handles to each of the fd_set sets of interest by using the FD_SET macro.

  3. Call the select function and wait until I/O activity sets one or more of the socket handles in each fd_set set provided. When selectcompletes, it returns the total number of socket handles that are set in all of the fd_set sets and updates each set accordingly.

  4. Using the return value of select, your application can determine which application sockets have I/O pending by checking each fd_setset using the FD_ISSET macro.

  5. After determining which sockets have I/O pending in each of the sets, process the I/O and go to step 1 to continue the selectprocess.

When select returns, it modifies each of the fd_set structures by removing the socket handles that do not have pending I/O operations. This is why you should use the FD_ISSET macro as in step 4 to determine if a particular socket is part of a set. The following code sample outlines the basic steps needed to set up the select model for a single socket. Adding more sockets to this application simply involves maintaining a list or an array of additional sockets.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果你想要在 Bootstrap 创建一个可搜索的下拉选择框,你可以使用 Bootstrap Select 插件。Bootstrap Select 是一个基于 Bootstrap 的自定义下拉选择框插件,它提供了更多的功能和样式。 首先,将 Bootstrap 和 Bootstrap Select 的 CSS 和 JavaScript 文件引入到你的 HTML 文件。你可以从官方网站下载这些文件,或者使用 CDN 引入。例如: ```html <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-select@1.14.0/dist/css/bootstrap-select.min.css"> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/bootstrap-select@1.14.0/dist/js/bootstrap-select.min.js"></script> ``` 接下来,你可以在 HTML 创建一个选择框,并使用 `selectpicker` 类来初始化它作为 Bootstrap Select。例如: ```html <select class="selectpicker" data-live-search="true"> <option>选项1</option> <option>选项2</option> <option>选项3</option> </select> ``` 在上面的代码,`selectpicker` 类用于初始化下拉选择框,并且 `data-live-search="true"` 属性将启用搜索功能。 在页面加载完成后,你需要调用一段 JavaScript 代码来初始化 Bootstrap Select。例如: ```javascript $(document).ready(function() { $('.selectpicker').selectpicker(); }); ``` 这样就可以使用 Bootstrap Select 来创建一个可搜索的下拉选择框了。你可以根据需要进一步自定义和配置选择框的样式和功能。更多关于 Bootstrap Select 的用法和选项,请参考官方文档。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值