【问题标题】:Is a socket still writable even if your network connection is disconnected?即使您的网络连接断开,套接字仍然可写吗?
【发布时间】:2012-03-18 08:30:26
【问题描述】:

我有这段代码,用于检查 UDP 套接字是否可写,如果可写,它应该发送一些数据。我需要连续发送数据,但只要我的互联网连接断开,它就应该停止发送。该应用程序在使用调制解调器的计算机上运行,​​但有时调制解调器会挂断,但我的应用程序仍然尝试发送数据,但它不知道互联网连接不再可用。

打开 UDP 套接字

int socket_fd;
addr.sin_family = AF_INET;
addr.sin_port = htons(999);
addr.sin_addr.s_addr = ip_of_server; 

socket_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
bind(fd, (struct sockaddr*)&addr, sizeof(addr));

检查套接字是否可写然后发送一些数据

struct timeval tv;
fd_set write_fds;
int ready;

tv.tv_sec = 0;
tv.tv_usec = 0;
FD_ZERO(&write_fds);
FD_SET(socket_fd, &write_fds);

ready = select(socket_fd + 1, NULL, &write_fds, NULL, &tv);

if ( ready && FD_ISSET(socket_fd, &write_fds) ) 
{

    //Send data here

}

我的问题是即使我断开互联网连接,select() 仍然报告套接字是可写的。 select() 真的是这样吗?它不应该告诉您由于网络连接已经断开,因此套接字不可写吗?

什么是最好的解决方案?

【问题讨论】:

  • 如果您发送数据,那么您会得到某种响应,对吧?
  • 如果我使用 sendto() 发送,则不会报告错误,它就像实际发送一样。
  • 您不会在此处收到任何错误报告。 sendto的作用只是通过网络发送数据,并不检查数据是否到达对方。
  • 我说的是你是否从接收者那里得到任何返回数据。我的意思是你在使用recvfrom 或其他类似的功能吗?

标签: c sockets select


【解决方案1】:

UDP 套接字始终是可写的。

您应该只使用 select() 来轮询 tcp 套接字是否可写。

【讨论】:

  • 感谢您澄清这一点。我现在有一个计划来监听网络变化,这在question 上说是可能的
【解决方案2】:

由于您正在发送数据,我猜您也会收到来自另一方的某种响应。如果是这种情况,那么在发送请求后,您可以等待一段时间的回复,如果您的数据发送机制是同步的(您发送数据,接收响应,然后再次发送数据)。如果该间隔到期,那么您应该假设网络不工作并且您的连接中断,因此终止您的应用程序。

如果您的数据发送机制不是同步的(无论您收到什么响应,您都会连续发送数据),那么您应该启动一个线程来更新某种计时器。如果在定时器到达某个阈值之前没有收到任何响应(您应该根据自己的要求决定),那么您可以假设网络中断,然后终止应用程序。

【讨论】:

    猜你喜欢
    • 2020-06-27
    • 2013-04-13
    • 2019-06-03
    • 2015-06-21
    • 1970-01-01
    • 1970-01-01
    • 2016-03-28
    • 2021-06-29
    • 1970-01-01
    相关资源
    最近更新 更多