手工断网后 send返回值竟为发送成功!?

vivian苹果 2013-06-20 10:18:28
小弟自己尝试书写一个TCP客户端、服务器端通信例子。编译完成后运行一切正常。突发奇想想看看断网后send会返回何种错误,是否如同msdn所述(一切都要经过自己确认记忆才深嘛)。
connect连接正常后,断点调试暂停运行,在send需要发送数据之前,手工拔掉网线后,继续执行send发送数据,本以为会返回SOCKET_ERROR,但事实是send返回值为发送缓冲区总字节(意味发送成功)。
以下为实际情况截图:
第一步:
断点暂停执行在send发送数据前;


第二步:
手工拔掉网线;



第三步:
执行send发送。



小弟不解,请各位大大围观解析下
...全文
910 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
忧伤绿豆 2015-08-03
  • 打赏
  • 举报
回复
send做的是,把数据交付给tcp,交付完就返回成功了。 tcp传送失败了也没处返回了 本身socket就不可靠
__lhy 2013-06-21
  • 打赏
  • 举报
回复
引用 楼主 u010076809 的回复:
小弟自己尝试书写一个TCP客户端、服务器端通信例子。编译完成后运行一切正常。突发奇想想看看断网后send会返回何种错误,是否如同msdn所述(一切都要经过自己确认记忆才深嘛)。 connect连接正常后,断点调试暂停运行,在send需要发送数据之前,手工拔掉网线后,继续执行send发送数据,本以为会返回SOCKET_ERROR,但事实是send返回值为发送缓冲区总字节(意味发送成功)。 以下为实际情况截图: 第一步: 断点暂停执行在send发送数据前; 第二步: 手工拔掉网线; 第三步: 执行send发送。 小弟不解,请各位大大围观解析下
原因就是send没有真正发送 返回值表示提交到发送缓冲区成功
13东倍 2013-06-20
  • 打赏
  • 举报
回复
引用 11 楼 u010076809 的回复: Quote: 引用 9 楼 zhao4zhong1 的回复: 真正的发送成功,只在接到来自对方“确认已收到”消息的那一刻之后。 按照您所说,倘若真正发送成功后,对方也接收到,要给予返回表示接收成功并处理成功,但此刻断网,发送方无法接收返回方返回的处理成功确认,这时候我们只要获取发送成功,剩余的返回方处理结果我们毫不关心,此刻结合上述我所言问题,价值便体现出来了。 问题是只有上帝知道“真正发送成功后,对方也接收到,要给予返回表示接收成功并处理成功
vivian苹果 2013-06-20
  • 打赏
  • 举报
回复
引用 14 楼 adlay 的回复:
不是啥子奇异想法,禁用缓冲虽不算很常用,但还是有被使用的。也没有啥子不正规的。
vivian苹果 2013-06-20
  • 打赏
  • 举报
回复
引用 13 楼 zhao4zhong1 的回复:
[quote=引用 11 楼 u010076809 的回复:] [quote=引用 9 楼 zhao4zhong1 的回复:] 真正的发送成功,只在接到来自对方“确认已收到”消息的那一刻之后。
按照您所说,倘若真正发送成功后,对方也接收到,要给予返回表示接收成功并处理成功,但此刻断网,发送方无法接收返回方返回的处理成功确认,这时候我们只要获取发送成功,剩余的返回方处理结果我们毫不关心,此刻结合上述我所言问题,价值便体现出来了。[/quote] 问题是只有上帝知道“真正发送成功后,对方也接收到,要给予返回表示接收成功并处理成功”[/quote] 忘记说明该主题啦,是要我们开发人员知道应急处理,不是上帝
www_adintr_com 2013-06-20
  • 打赏
  • 举报
回复
不是啥子奇异想法,禁用缓冲虽不算很常用,但还是有被使用的。也没有啥子不正规的。
赵4老师 2013-06-20
  • 打赏
  • 举报
回复
引用 11 楼 u010076809 的回复:
[quote=引用 9 楼 zhao4zhong1 的回复:] 真正的发送成功,只在接到来自对方“确认已收到”消息的那一刻之后。
按照您所说,倘若真正发送成功后,对方也接收到,要给予返回表示接收成功并处理成功,但此刻断网,发送方无法接收返回方返回的处理成功确认,这时候我们只要获取发送成功,剩余的返回方处理结果我们毫不关心,此刻结合上述我所言问题,价值便体现出来了。[/quote] 问题是只有上帝知道“真正发送成功后,对方也接收到,要给予返回表示接收成功并处理成功”
vivian苹果 2013-06-20
  • 打赏
  • 举报
回复
引用 10 楼 adlay 的回复:
把这个 SO_SNDBUF 缓冲大小设置为 0

按照您所述,代码如下:
int nBuffLen = 0;
int nRet = setsockopt(svc_scoket, SOL_SOCKET, SO_SNDBUF, (char *)&nBuffLen , sizeof( int ));

效果如图:


先生的奇异思想真的太厉害啦啦啦啦啦!~~ 困扰本人一天的问题终于得到解决了,虽然不是很正规的做法,但效果很棒。。。
vivian苹果 2013-06-20
  • 打赏
  • 举报
回复
引用 9 楼 zhao4zhong1 的回复:
真正的发送成功,只在接到来自对方“确认已收到”消息的那一刻之后。
按照您所说,倘若真正发送成功后,对方也接收到,要给予返回表示接收成功并处理成功,但此刻断网,发送方无法接收返回方返回的处理成功确认,这时候我们只要获取发送成功,剩余的返回方处理结果我们毫不关心,此刻结合上述我所言问题,价值便体现出来了。
www_adintr_com 2013-06-20
  • 打赏
  • 举报
回复
把这个 SO_SNDBUF 缓冲大小设置为 0
赵4老师 2013-06-20
  • 打赏
  • 举报
回复
真正的发送成功,只在接到来自对方“确认已收到”消息的那一刻之后。
vivian苹果 2013-06-20
  • 打赏
  • 举报
回复
引用 7 楼 zhao4zhong1 的回复:
所以才需要有心跳包嘛。
可是我设置的心跳包为30秒,在下次心跳来之前发生此种状况,又需要立刻获取是否真正发送成功的状态的话,心跳包帮助不大。
赵4老师 2013-06-20
  • 打赏
  • 举报
回复
所以才需要有心跳包嘛。
vivian苹果 2013-06-20
  • 打赏
  • 举报
回复
回2楼,但我想测试的是在send之前断网后,想获取到该send发送失败的状态。
依然查看了下另外一位朋友的博客: http://blog.csdn.net/guomsh/article/details/8484207#comments
写得很棒。
但参照里面的设置socket keep alive,但由于我是window网络编程,所以只能设置如下:
int nRet = setsockopt(svc_scoket, SOL_SOCKET, SO_KEEPALIVE, (void *)&keepalive , sizeof(keepalive ));

微软说明:


它说我们只能设置为布尔值,仅仅只能启动开关,不能入微操作。甚是苦恼啊
vivian苹果 2013-06-20
  • 打赏
  • 举报
回复
谢谢。懂了
nice_cxf 2013-06-20
  • 打赏
  • 举报
回复
引用 3 楼 u010076809 的回复:
回2楼,“拔本机的网线后是取不到socket的”,这句话可否详细点
假定本地地址192.168.1.100 假如你拔掉本地网线,你无法在用到这个ip地址,对c程序来说,拔网线基本等同禁用
vivian苹果 2013-06-20
  • 打赏
  • 举报
回复
回2楼,“拔本机的网线后是取不到socket的”,这句话可否详细点
nice_cxf 2013-06-20
  • 打赏
  • 举报
回复
拔对面的网线,不要拔本机的试试?拔本机的网线后是取不到socket的
vivian苹果 2013-06-20
  • 打赏
  • 举报
回复
引荐http://blog.csdn.net/zzsfqiuyigui/article/details/7073527 但依然不能解决问题。 if ( INVALID_SOCKET == ( svc_scoket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ) ) ) { _validateSign = false; delete[] recvbuf; recvbuf = NULL; LC_PubFunValue::setSysState(4, "1"); _cErrorCode = "APP0027"; response->setRetCode("APP0027"); response->setSendFailStatus(); return response; } BOOL chOpt = TRUE; int nErr = setsockopt( svc_scoket, IPPROTO_TCP, TCP_NODELAY, ( char* )&chOpt, sizeof( chOpt ) ); int optVal = 1024; int Err= setsockopt( svc_scoket, SOL_SOCKET, SO_SNDBUF, ( char* )&optVal, sizeof( optVal ) ); int nNetTimeout = 1000; // 1 sec int nRet = setsockopt( svc_scoket, SOL_SOCKET, SO_KEEPALIVE, ( char* )&chOpt, sizeof( BOOL ) ); int nRet1 = setsockopt( svc_scoket, SOL_SOCKET, SO_RCVBUF, ( char* )&optVal, sizeof( int ) ); int nRet2 = setsockopt( svc_scoket, SOL_SOCKET, SO_SNDTIMEO, ( char* )&nNetTimeout, sizeof( int ) ); nRet2 = setsockopt( svc_scoket, SOL_SOCKET, SO_RCVTIMEO, ( char* )&nNetTimeout, sizeof( int ) ); 上述设置socket属性已经显示成功,但在send发送前拔掉网线(断网),send返回值依然为缓冲区总字长,没有驱动协议去真正发送,并且直接返回。 求观摩~。

33,311

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 新手乐园
社区管理员
  • 新手乐园社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧