2017-04-12 62 views
0

我正在用C++编写一个套接字程序。该程序在一组集群机器上运行。处理TCP失败的正确机制是什么?

我刚刚进入套接字编程,刚学会如何发送和接收。我认为,在程序长时间运行期间,某些TCP连接可能会丢失。在这种情况下,需要平滑地重新连接服务器和客户端。

我不知道是否有一个众所周知的基本机制(或算法?协议?)来实现它。我发现有许多不同的语义的套接字错误代码,这使我很难开始。

任何人都可以建议我可以学习的任何参考代码吗?

谢谢,

+0

当TCP连接失败时,通常是以致命的方式。处理TCP连接失败的“标准”方法就是关闭连接并尝试重新连接。 –

回答

3

这并不复杂。这不是致命的连接只有两个错误代码是:

  • EAGAIN/EWOULDBLOCK,这实际上是两个名称相同的号码,意味着它是确定以重新尝试之后的操作期间或之后select()/poll()/epoll()已如此指示; EINTR,只是意味着'中断系统调用' - 再试一次。

所有其他人都致命的连接,并应导致你关闭它。

+0

连接可以从中恢复的非致命错误,如'ENETUNREACH'。当存在网络中断而暂时适应的网络应用程序被打破。 – Kaz

+0

@Kaz应用程序只能通过对路由表执行某些操作才能从ENETUNREACH中恢复。 – EJP

+0

由某人/某事对路由表做些什么,不一定是应用程序。 – Kaz

-1

实际的具体错误代码是不相关的。如果你有一个活动的套接字连接,失败的读或写表明连接已经消失。错误代码可能会给你一些解释,但现在已经太晚了。插座不见了。没有更多。它不复存在。这是一个ex-socket。您可以使用错误代码来提出丰富多彩的解释,但这只是一些小小的安慰。不管具体的原因是什么,但你的套接字已经消失,你必须处理它。

当使用非阻塞套接字时,会有某些特定的返回码和errno值表明套接字仍然正常,但尚未准备好读取或写入任何内容,您必须专门检查,并且处理。这将是唯一的例外。

另外,EINTR通常并不一定意味着插座是真的破损;所以这可能是另一个例外检查。

一旦你有一个破损的套接字,唯一的一般设计原则,如果有的话,那就是你必须把它作为第一个业务订单。文件描述符是完全没用的。在那之后,完全取决于你下一步做什么。对于这种情况,没有任何规则刻在石头上。通常,应用程序会以某种形式或方式记录错误,或试图建立另一个连接。通常由你决定要做什么。

关于套接字编程中唯一的“众所周知的基本机制”是明确的超时。网络错误和故障并不总是立即被底层操作系统检测到。发生网络问题时,并不总是可以立即检测到。在协议栈声明一个破损的套接字之前可能需要很多分钟,并且会给出错误指示。因此,如果你正在编码一个特定的应用程序,并且你知道你应该在某个规定的时间范围内读或写某些东西,那么一个通用的设计模式就是编写一个明确的超时,如果没有任何事情发生,超时到期,假设套接字已损坏 - 即使您没有明确的错误指示,否则 - close()它,然后继续下一步。

+0

使用EAGAIN/EWOULDBLOCK或EINTR时,读取或写入操作可能会失败,其中* none *表示“连接已中断”。如果存在读取超时设置,则可以在阻塞模式下获得EAGAIN/EWOULDBLOCK。 – EJP

相关问题