阻塞套接字 - 检测状态

Posted

技术标签:

【中文标题】阻塞套接字 - 检测状态【英文标题】:Blocking socket - detect state 【发布时间】:2012-12-18 18:31:35 【问题描述】:

我正在开发我的第一个 c/c++ 应用程序并使用套接字。此应用程序连接到服务器并读取从服务器发送的图像数据,图像数据前面有一些感兴趣的整数,例如要读取多少数据。

该应用程序正在使用阻塞套接字,因为我认为在有阻塞选项直到数据可用时让我的线程持续循环不会更好。

我现在的问题是,如果服务器只是失去与网络的连接,我的应用程序就坐在那里,我无法向用户触发通知或尝试重新连接。我不知道如何检查连接状态。

有人可以就如何解决我的问题给我一些建议吗?

谢谢。我已经粘贴了我的 readImageInt() 函数,它显示了我是如何从套接字读取的。我正在使用 linux 设备进行开发。

int readImageInt()


int nb, i;
union 
    long int whole;
    char bytes[4];
 v;
memset(v.bytes, 0x00, 4);
nb = recv(imagesock, v.bytes, 4, MSG_WAITALL);
if (nb == 0||nb == -1)
 

    return -1;
 
else
    
    v.whole = ntohl(v.whole);

     return v.whole;
    


【问题讨论】:

您是否将套接字创建为SOCK_STREAM 是的,imagesock = socket(AF_INET, SOCK_STREAM, 0) 你怎么不用IPPROTO_TCP?我假设它是 tcp。 第一个应用程序 Nick,那是个错误吗?我会做一些阅读,但它是否解决了提到的问题? 可能,socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) 【参考方案1】:

你可以设置SO_RCVTIMEOsocket option突破长阻塞接收操作。

编辑0:

或者,您可以使用像select(2)poll(2)(或epoll_wait(2),如果您在Linux 上)这样的轮询调用来超时。这将允许您跳出内核等待检查,例如,一些用户输入告诉您是继续等待还是放弃。

检测断开连接的更可靠方法是发送数据,如果对方支持它 - 你会收到一个信号或错误返回(虽然在崩溃的远程端可能在分钟)。

编辑 1:

看看select_tut(2)

【讨论】:

谢谢 Nikolai,理想情况下我想阻止,直到数据返回或发生断开连接 - 这可能吗? 感谢您对使用 select 的两个建议,我试图弄清楚如何在我的设置中使用 select - 例如,我将在 readimageint 中做什么 - 在 select 中循环持续 1 秒然后跳出循环并读取数据是否可用或如果返回错误则通知?我只是认为在 recv(无循环)处阻塞更有效。 除非你想早点爆发,否则效率更高。 所以我可以在不设置超时的情况下使用 select 并且只有在数据可用或连接关闭时才会返回? 是的,但这与阻止 recv() 没有什么不同 - 如果远程端从网络上掉下来,你永远不会知道,除非你设置了超时。【参考方案2】:

您可以考虑在接收任何数据之前使用 select 函数来检查您的套接字的状态。见这里例如http://support.sas.com/documentation/onlinedoc/sasc/doc750/html/lr2/select.htm

【讨论】:

以上是关于阻塞套接字 - 检测状态的主要内容,如果未能解决你的问题,请参考以下文章

非阻塞式I/O

如何为 3 个不同的事件(信号量、pthread 条件和阻塞套接字接收)阻塞单个线程?

网络编程中的超时检测

C++非阻塞键盘缓冲区输入检测或读取函数是啥?

并发编程 - 协程 - 1.协程概念/2.greenlet模块/3.gevent模块/4.gevent实现并发的套接字通信

Socket I/O模型之select模型