C语言 套接字编程中的选择函数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4171270/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 07:01:38  来源:igfitidea点击:

Select function in socket programming

cnetworkingnetwork-programming

提问by user484457

Can anyone tell me the use and application of selectfunction in socket programming in c?

谁能告诉我select函数在c中socket编程中的使用和应用?

回答by Ziffusion

The select()function allows you to implement an event driven design pattern, when you have to deal with multiple event sources.

select()当您必须处理多个事件源时,该函数允许您实现事件驱动的设计模式。

Let's say you want to write a program that responds to events coming from several event sources e.g. network (via sockets), user input (via stdin), other programs (via pipes), or any other event source that can be represented by an fd. You could start separate threads to handle each event source, but you would have to manage the threads and deal with concurrency issues. The other option would be to use a mechanism where you can aggregate all the fdinto a single entity fdset, and then just call a function to wait on the fdset. This function would return whenever an event occurs on any of the fd. You could check which fdthe event occurred on, read that fd, process the event, and respond to it. After you have done that, you would go back and sit in that wait function - till another event on some fdarrives.

假设您要编写一个程序来响应来自多个事件源的事件,例如网络(通过套接字)、用户输入(通过标准输入)、其他程序(通过管道)或任何其他可以由fd. 您可以启动单独的线程来处理每个事件源,但您必须管理线程并处理并发问题。另一种选择是使用一种机制,您可以将所有这些聚合fd到一个实体中fdset,然后只需调用一个函数来等待fdset. 每当在任何fd. 你可以检查哪个fd事件发生了,阅读fd,处理事件并响应它。完成此操作后,您将返回并坐在该等待函数中 - 直到某些事件fd到达。

selectfacility is such a mechanism, and the select()function is the wait function. You can find the details on how to use it in any number of books and online resources.

select设施就是这样一种机制,而select()函数就是等待函数。您可以在任意数量的书籍和在线资源中找到有关如何使用它的详细信息。

回答by Collin

The selectfunction allows you to check on several different sockets or pipes (or any file descriptors at all if you are not on Windows), and do something based on whichever one is ready first. More specifically, the arguments for the selectfunction are split up into three groups:

select函数允许您检查几个不同的套接字或管道(如果您不在 Windows 上,则可以检查任何文件描述符),并根据哪个先准备好做一些事情。更具体地说,该select函数的参数分为三组:

  • Reading: When any of the file descriptors in this category are ready for reading, select will return them to you.

  • Writing: When any of the file descriptors in this category are ready for writing, select will return them to you.

  • Exceptional: When any of the file descriptors in this category have an exceptional case -- that is, they close uncleanly, a connection breaks or they have some other error -- selectwill return them to you.

  • 读取:当该类别中的任何文件描述符准备好读取时,select 会将它们返回给您。

  • 写入:当此类别中的任何文件描述符准备好写入时,select 会将它们返回给您。

  • Exceptional:当此类别中的任何文件描述符出现异常情况时——即,它们不干净地关闭、连接中断或它们有一些其他错误——select将返回给您。

The power of selectis that individual file/socket/pipe functions are often blocking. Select allows you to monitor the activity of several different file descriptors without having to have a dedicated thread of your program to each function call.

的强大之select处在于单个文件/套接字/管道功能通常是阻塞的。Select 允许您监视多个不同文件描述符的活动,而不必为每个函数调用设置专用的程序线程。

In order for you to get a more specific answer, you will probably have to mention what language you are programming in. I have tried to give as general an answer as possible on the conceptual level.

为了让您获得更具体的答案,您可能必须提及您正在使用哪种语言进行编程。我已尝试在概念层面给出尽可能笼统的答案。

回答by Chris

select() is the low-tech way of polling sockets for new data to read or for an open TCP window to write. Unless there's some compelling reason not to, you're probably better off using poll(), or epoll_wait() if your platform has it, for better performance.

select() 是轮询套接字以读取新数据或打开 TCP 窗口写入的低技术方式。除非有一些令人信服的理由不这样做,否则最好使用 poll() 或 epoll_wait()(如果您的平台有),以获得更好的性能。

回答by David Parks

More detail would be good, but I think you're referring to Java NIO's Selector.select() method.

更多细节会很好,但我认为您指的是 Java NIO 的 Selector.select() 方法。

The simple answer to your question is that select() (in this context) will wait for a channel (that is, one of the network connections that's being managed by this Selector object) has data available to read.

对您的问题的简单回答是 select() (在此上下文中)将等待一个通道(即,由该 Selector 对象管理的网络连接之一)具有可供读取的数据。

When you have many connections open at once, many/most will be dormant at any given moment. This method/class allows you to manage many connections without having a separate for each connection blocking on that connection. You can block with one thread for multiple connections and simply receive back whichever connection(s) are "ready" at the moment.

当您同时打开许多连接时,许多/大多数将在任何给定时刻处于休眠状态。此方法/类允许您管理许多连接,而无需为该连接上的每个连接单独阻塞。您可以使用一个线程阻塞多个连接,然后简单地接收当前“就绪”的任何连接。

Here's a great little tutorial that should make things clear:

这是一个很棒的小教程,可以让事情变得清晰:

http://rox-xmlrpc.sourceforge.net/niotut/

http://rox-xmlrpc.sourceforge.net/niotut/

回答by Steve-o

Per the documentation for Linux manpages and MSDN for Windows,

根据 Linux 联机帮助页和 MSDN for Windows 的文档,

select() and pselect() allow a program to monitor multiple file descriptors, waiting until one or more of the file descriptors become "ready" for some class of I/O operation (e.g., input possible). A file descriptor is considered ready if it is possible to perform the corresponding I/O operation (e.g., read(2)) without blocking.

select() 和 pselect() 允许程序监视多个文件描述符,等待一个或多个文件描述符“准备好”进行某类 I/O 操作(例如,可能的输入)。如果可以在不阻塞的情况下执行相应的 I/O 操作(例如 read(2)),则认为文件描述符已准备就绪。

For simple explanation: often it is required for an application to do multiple things at once. For example you may access multiple sites in a web browser, a web server may want to serve multiple clients simultaneously. One needs a mechanism to monitor each socket so that the application is not busy waiting for one communication to complete.

简单解释一下:通常需要一个应用程序一次做多件事。例如,您可能会在 Web 浏览器中访问多个站点,Web 服务器可能希望同时为多个客户端提供服务。需要一种机制来监视每个套接字,以便应用程序不会忙于等待一个通信完成。

An example: imagine downloading a large Facebook page on your smart phone whilst traveling on a train. Your connection is intermittent and slow, the web server should be able to process other clients when waiting for your communication to finish.

一个例子:想象一下在火车上旅行时在你的智能手机上下载一个大的 Facebook 页面。您的连接时断时续且速度缓慢,在等待您的通信完成时,Web 服务器应该能够处理其他客户端。

回答by fat

I like description at gnu.org:

我喜欢gnu.org 上的描述

Sometimes a program needs to accept input on multiple input channels whenever input arrives. For example, some workstations may have devices such as a digitizing tablet, function button box, or dial box that are connected via normal asynchronous serial interfaces; good user interface style requires responding immediately to input on any device. [...]

You cannot normally use readfor this purpose, because this blocks the program until input is available on one particular file descriptor; input on other channels won't wake it up. You could set nonblocking mode and poll each file descriptor in turn, but this is very inefficient.

A better solution is to use the selectfunction. This blocks the program until input or output is ready on a specified set of file descriptors, or until a timer expires, whichever comes first.

有时,程序需要在输入到达时接受多个输入通道上的输入。例如,某些工作站可能具有通过普通异步串行接口连接的数字化板、功能按钮盒或拨号盒等设备;良好的用户界面风格需要立即响应任何设备上的输入。[...]

通常不能read用于此目的,因为这会阻塞程序,直到在某个特定文件描述符上有可用输入;其他通道上的输入不会唤醒它。您可以设置非阻塞模式并轮询每个文件描述符,但这非常低效。

更好的解决方案是使用该select函数。这会阻塞程序,直到在一组指定的文件描述符上准备好输入或输出,或者直到计时器到期,以先到者为准。