阻塞式套接字 - 检测状态

3
我正在开发我的第一个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 - imreal
是的,imagesock = socket(AF_INET, SOCK_STREAM, 0) - user1379811
为什么你没有使用IPPROTO_TCP?我猜它是TCP。 - imreal
第一个应用程序 Nick,那是个错误吗?我会查阅一些资料,但它是否解决了提到的问题? - user1379811
可能是 socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) - imreal
谢谢Nick,我现在明白SOCK_STREAM和IPPROTO_TCP是一起使用的。但这并不能帮助解决当前的情况。 - user1379811
2个回答

1

您可以设置SO_RCVTIMEO 套接字选项以跳出长时间阻塞的接收操作。

编辑0:

或者,您可以使用轮询调用,例如{{link3:select(2)}},{{link4:poll(2)}}(如果您在Linux上,则为{{link5:epoll_wait(2)}})并设置超时。这将允许您跳出内核等待以检查某些用户输入,告诉您是否继续等待或退出。

检测断开连接的更可靠方法是发送数据,如果另一端支持,则会收到信号或错误返回(尽管在崩溃的远程端可能需要几分钟)。

编辑1:

请查看{{link1:select_tut(2)}}。


谢谢Nikolai,理想情况下我希望能够阻塞直到数据返回或发生断开连接 - 这可能吗? - user1379811
感谢您提供使用select的建议,我正在努力理解如何在我的设置中使用select - 例如,在readimageint中我该怎么做 - 在select中循环并设置1秒的超时时间,然后跳出循环并读取数据是否可用或通知返回错误?我只是认为在recv处阻塞(不循环)更有效率。 - user1379811
它更有效率,除非你想要早点退出。 - Nikolai Fetissov
那么我可以在不设置超时的情况下使用select,只有在数据可用或连接关闭时才会返回? - user1379811
是的,但这与阻塞recv()没有什么不同 - 如果远程端掉线了,你将永远不会知道,除非你设置超时。 - Nikolai Fetissov

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接