在套接字编程中选择功能

时间:2010-11-13 06:18:07

标签: c networking network-programming

有谁可以告诉我select函数在c?

中的套接字编程中的用法和应用

6 个答案:

答案 0 :(得分:45)

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

假设您要编写一个程序来响应来自多个事件源的事件,例如:网络(通过套接字),用户输入(通过stdin),其他程序(通过管道),或任何其他可由fd表示的事件源。您可以启动单独的线程来处理每个事件源,但您必须管理线程并处理并发问题。另一种选择是使用一种机制,您可以将所有fd聚合到单个实体fdset中,然后调用一个函数来等待fdset。只要在任何fd上发生事件,此函数就会返回。您可以查看事件发生的fd,阅读fd,处理事件并回复。完成后,您将返回并参与等待功能 - 直到某些fd上的其他事件到达。

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

答案 1 :(得分:9)

select函数允许您检查几个不同的套接字或管道(或者如果您不在Windows上,则根本不检查任何文件描述符),并根据先准备好的任何内容执行某些操作。更具体地说,select函数的参数分为三组:

读: 当此类别中的任何文件描述符准备好阅读时,选择将返回给您。

写作: 当此类别中的任何文件描述符准备好写入时,选择将返回给您。

例外: 当此类别中的任何文件描述符具有例外情况时 - 即,它们不正常地关闭,连接断开,或者它们有其他错误 - 选择将返回给您。

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

为了让你得到一个更具体的答案,你可能不得不提到你正在编程的语言。我试图在概念层面给出一般答案。

答案 2 :(得分:4)

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

答案 3 :(得分:2)

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

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

当您同时打开许多连接时,许多/大多数将在任何给定时刻处于休眠状态。此方法/类允许您管理多个连接,而不必为该连接上的每个连接阻塞单独使用。您可以使用一个线程阻止多个连接,并且只需接收当前“准备好”的任何连接。

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

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

答案 4 :(得分:0)

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

  

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

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

一个例子:想象一下在火车上下载智能手机上的大型Facebook页面。您的连接是间歇性和缓慢的,Web服务器应该能够在等待您的通信完成时处理其他客户端。

答案 5 :(得分:0)

我喜欢gnu.org:

的说明
  

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

     

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

     

更好的解决方案是使用select功能。 这会阻止程序,直到输入或输出在指定的文件描述符集上就绪,或者直到计时器到期为止,以先到者为准。