Chinaunix

标题: 老鸟的新问题 [打印本页]

作者: sczhang_0001    时间: 2012-10-23 14:10
标题: 老鸟的新问题
呵呵,请教一个比较菜的问题啊。 linux/C TCP/IP相关的。
client 和 server之间有个tcp 连接。
client会定时给server发一个自己定义的keep alive数据,但是服务器不用回。
client需要能检测到网络断开,比如服务器挂了或网线断了。
但是client这边的发送一直返回成功,(tcp底层有重传,但是异步发送返回一直是成功的)。
有什么好办法检测啊。

谢谢各位兄弟!

作者: lxyscls_cu    时间: 2012-10-23 14:50
很腻害的样纸{:3_189:}

《TCP/IP高效编程》技巧10,俺没看过{:3_188:}

希望对您有帮助
作者: linux_c_py_php    时间: 2012-10-23 15:27
楼主典型的新手, 其实UDP和TCP是一样的, TCP只不过是字节流, 一样是一包一包的, 有的包是用来keepalive的, 有的包是普通数据, 能理解吗?
作者: sczhang_0001    时间: 2012-10-24 00:33
楼上的兄弟,我还真不明白。
这个keepalive 是我们自己的协议规定的,它不是tcp里面那个keep alive。
我就发两对回车换行,也是普通数据而已。
这样子服务器端自然很容易知道连接是否断掉,他只要判断在一定时间里有没有数据收到。

我的问题是,客户端这边怎么知道,因为发送总是成功,即使没收到ACK,我不熟悉TCP,所以也不太理解为何,似乎只要成功放到发送缓冲区就算成功了,至于有没有被对端tcp层接收就不知道了。

我有看到tcp的重传,但是作为应用程序似乎无法知道自己的数据因为网络原因没有到达对方TCP层。

我需要想个办法知道我没有收到我发的数据的ACK,然后做出网络断开的判断。


作者: linux_c_py_php    时间: 2012-10-24 10:36
-,- 我说的就是应用层的keepalive心跳包, TCP和UDP都是一样的道理, 任何一端都要定时向对方发送, 任何一端都要定时检测对方是否定时发送.
作者: db1984    时间: 2012-10-24 10:50
回复 4# sczhang_0001

有办法知道,但是实现的代价远远大于你服务端直接回应点什么
你这就是应用层的心跳,本来就应该在里实现

   
作者: chinesedragon    时间: 2012-10-24 10:55
最好还是服务器和客户端有交互,这样做起来更容易
作者: skychgg    时间: 2012-10-25 08:27
5.14 Crashing of Server Host
This scenario will test to see what happens when the server host crashes. To simulate this, we must run the client and server on different hosts. We then start the server, start the client, type in a line to the client to verify that the connection is up, disconnect the server host from the network, and type in another line at the client. This also covers the scenario of the server host being unreachable when the client sends data (i.e., some intermediate router goes down after the connection has been established).

The following steps take place:

When the server host crashes, nothing is sent out on the existing network connections. That is, we are assuming the host crashes and is not shut down by an operator (which we will cover in Section 5.16).

We type a line of input to the client, it is written by writen (Figure 5.5), and is sent by the client TCP as a data segment. The client then blocks in the call to readline, waiting for the echoed reply.

If we watch the network with tcpdump, we will see the client TCP continually retransmitting the data segment, trying to receive an ACK from the server. Section 25.11 of TCPv2 shows a typical pattern for TCP retransmissions: Berkeley-derived implementations retransmit the data segment 12 times, waiting for around 9 minutes before giving up. When the client TCP finally gives up (assuming the server host has not been rebooted during this time, or if the server host has not crashed but was unreachable on the network, assuming the host was still unreachable), an error is returned to the client process. Since the client is blocked in the call to readline, it returns an error. Assuming the server host crashed and there were no responses at all to the client's data segments, the error is ETIMEDOUT. But if some intermediate router determined that the server host was unreachable and responded with an ICMP "destination unreachable' message, the error is either EHOSTUNREACH or ENETUNREACH.

Although our client discovers (eventually) that the peer is down or unreachable, there are times when we want to detect this quicker than having to wait nine minutes. The solution is to place a timeout on the call to readline, which we will discuss in Section 14.2.

The scenario that we just discussed detects that the server host has crashed only when we send data to that host. If we want to detect the crashing of the server host even if we are not actively sending it data, another technique is required. We will discuss the SO_KEEPALIVE socket option in Section 7.5.
注:本段内容摘自UNIX网络编程第一卷第五章,根据上述描述及本人理解,若服务端异常关闭,客户端在接收时会返回错误。
作者: starwing83    时间: 2012-10-25 08:52
本帖最后由 starwing83 于 2012-10-25 08:58 编辑

回复 1# sczhang_0001


    在客户端和服务器没有实质性的交互的前提下,是不可能知道服务器是否断开的。

TCP下面,你发送一个包,要知道是否成功肯定有ACK,想办法看能不能得到这个ACK吧。

最简单的方法还是和服务器交互,只要逻辑上服务器得发给你一个包,你就很容易就知道是不是断开了。

对了,关于发送,如果是同步的,想办法看看能不能得到一个“timeout”的结果,应该会返回ETIMEOUT的,异步的话,也应该有相应的机制。你用的是什么类型的异步?select类型的还是aio类型的?不同的类型有不同的方式应该。
作者: starwing83    时间: 2012-10-25 09:07
找到一个帖子,说的很详细,你可以看看:
http://cboard.cprogramming.com/l ... ken-connection.html




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2