2

我正在使用Gnat Sockets包。我有一个服务器端套接字,它已使用以下内容创建和初始化:

   GNAT.Sockets.Create_Socket(...);

...

   GNAT.Sockets.Set_Socket_Option
     (Socket => Server,
      Option => (Name => GNAT.Sockets.Receive_Timeout,
                 Timeout => Listner_Timeout));

...

   GNAT.Sockets.Listen_Socket(...);
   GNAT.Sockets.Accept_Socket(...);

到目前为止一切都很好,但是什么时候可以使用:

   GNAT.Sockets.Receive_Socket(...);

我不知道如何检测我的套接字是否超时,或者在它返回时读取一些数据。我是否需要使用该Check_Selector方法(这种用法似乎有点重,如果是这样,这是否与调用中设置的超时交互Set_Socket_Option)?

谢谢,

4

4 回答 4

3

在任何情况下,Check_Selector 上的 Timeout 参数都可以满足您的要求。您调用 Check_Selector(),并在它返回时查看状态。如果状态为完成,则您已获得“活动”,例如数据(假设您正在阅读)或套接字的另一端已关闭,如果已过期,则选择器超时,如果已中止,则命令选择器过早终止通过 Abort_Selector()。

我通常将套接字读取(包括 Check_Selector() 调用)放在任务中,以免阻塞应用程序的其余部分,并允许外部启动 Abort_Selector。事实上,我很少使用超时,我只是在套接字上循环检查/读取,当我不再需要读取套接字时,比如关闭时,只需调用 Abort_Selector() 即可完成。

于 2013-07-12T14:56:52.963 回答
0

我想我读到有人使用异步select来处理超时情况......比如:

loop
  select
    -- HANDLE SOCKET RECEPTION
   or
    delay 7.0; -- Wait seven seconds to timeout.
  end select;
end loop;

Note:以上内容来自内存,未经语法检查或编译。

于 2013-07-11T22:42:26.590 回答
0

我没有尝试过这个,但看起来你应该得到一个Socket_Error例外,也许,EWOULDBLOCK

如果数据只是涓涓细流,这可能效果不佳,因为每次一些数据到达时都会重置超时。

更新:我在 Mac OS X 上试过这个,得到GNAT.SOCKETS.SOCKET_ERROR: [35] Resource temporarily unavailable. [35] is EAGAINor EWOULDBLOCK(达尔文对两者使用相同的值,因此GNAT.Sockets故意做出模棱两可的报告)。

于 2013-07-12T08:03:49.317 回答
0

通过阅读Gnat.Sockets包规范(顺便说一句,你链接到的那个不支持Receive_Timeout),我的猜测Socket_Error被提出,它解决了(与Resolve_Exception)到Connection_Timed_Out.

另一种可能性是Receive_Socket返回Lastset to Item'First - 1,就好像套接字已被对等方关闭一样。

于 2013-07-12T08:35:32.277 回答