免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1701 | 回复: 9

[C] 老鸟的新问题 [复制链接]

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

谢谢各位兄弟!

论坛徽章:
0
发表于 2012-10-23 14:50 |显示全部楼层
很腻害的样纸{:3_189:}

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

希望对您有帮助

论坛徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46处女座
日期:2013-10-24 14:25:01酉鸡
日期:2014-04-07 11:54:15
发表于 2012-10-23 15:27 |显示全部楼层
楼主典型的新手, 其实UDP和TCP是一样的, TCP只不过是字节流, 一样是一包一包的, 有的包是用来keepalive的, 有的包是普通数据, 能理解吗?

论坛徽章:
0
发表于 2012-10-24 00:33 |显示全部楼层
楼上的兄弟,我还真不明白。
这个keepalive 是我们自己的协议规定的,它不是tcp里面那个keep alive。
我就发两对回车换行,也是普通数据而已。
这样子服务器端自然很容易知道连接是否断掉,他只要判断在一定时间里有没有数据收到。

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

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

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

论坛徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46处女座
日期:2013-10-24 14:25:01酉鸡
日期:2014-04-07 11:54:15
发表于 2012-10-24 10:36 |显示全部楼层
-,- 我说的就是应用层的keepalive心跳包, TCP和UDP都是一样的道理, 任何一端都要定时向对方发送, 任何一端都要定时检测对方是否定时发送.

论坛徽章:
0
发表于 2012-10-24 10:50 |显示全部楼层
回复 4# sczhang_0001

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

   

论坛徽章:
0
发表于 2012-10-24 10:55 |显示全部楼层
最好还是服务器和客户端有交互,这样做起来更容易

论坛徽章:
0
发表于 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网络编程第一卷第五章,根据上述描述及本人理解,若服务端异常关闭,客户端在接收时会返回错误。

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
发表于 2012-10-25 08:52 |显示全部楼层
本帖最后由 starwing83 于 2012-10-25 08:58 编辑

回复 1# sczhang_0001


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

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

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

对了,关于发送,如果是同步的,想办法看看能不能得到一个“timeout”的结果,应该会返回ETIMEOUT的,异步的话,也应该有相应的机制。你用的是什么类型的异步?select类型的还是aio类型的?不同的类型有不同的方式应该。

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
发表于 2012-10-25 09:07 |显示全部楼层
找到一个帖子,说的很详细,你可以看看:
http://cboard.cprogramming.com/l ... ken-connection.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP