TCP通信的时候,发送大量数据会死机?

totti1006 2010-10-18 06:29:37
我在MFC里面,用socket写了一个TCP通信的程序,异步套接字编程,注册了FD_READ | FD_WRITE | FD_CONNECT | FD_CLOSE事件。在客户端的主线程里面又创建了两个线程,一个线程不断的生成数据,另外一个线程把生成的数据发送出去,只要有数据生成就通过套接字发送。程序运行一段时间就会死机。
发送线程调用send函数发送数据,send(pFrame->m_socket, pBuf,length, 0);
我感觉数据生成的太多,在网络缓冲里面的数据还没有来得及发送的时候,又通过send函数往网络缓冲区中写数据了,最后内存耗尽,导致死机。
请问用什么方法可以解决这个问题呢?
在数据发送的时候如果知道网络发送缓冲区还有多大的空闲容量就可以确定是否要调用send函数了吧?如果网络发送缓冲区满了,就挂起发送数据的线程,如果网络发送缓冲区的空闲容量大于某个值了,就恢复发送数据的线程,这样可以吗?
怎么才能知道网络发送缓冲区是否已经满了?
如何知道网络发送缓冲区的空闲容量呢?
...全文
1071 22 打赏 收藏 转发到动态 举报
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
sun2006_20 2013-07-11
  • 打赏
  • 举报
回复
我也遇到同样的问题 ,不过我是uip在mcu上移植,运行一段时间之后再ping就会超时,pc端程序去发起连接的时候没有反应。
O112358 2010-10-27
  • 打赏
  • 举报
回复
内存泄漏,你自己接收或者发送代码有问题。我自己也有遇到过。
发送都是协议发的,不会出现那个问题。
如果自己设置的缓冲区过大,确实内存消耗很大。
不过应该是代码问题,建议自己检查下代码。
亚细亚 2010-10-27
  • 打赏
  • 举报
回复
应该是资源没有释放
wjb_yd 2010-10-26
  • 打赏
  • 举报
回复
我感觉八成是楼主自己的代码有内存泄露。
sunshine716 2010-10-20
  • 打赏
  • 举报
回复
我们都在盲人摸象,最好的办法就是把你的代码贴上来,根据代码分析。与缓存没有关系吧,Java里可以设置socket.setTcpNoDelay(true)不使用缓存,vc肯定也能,那你也设置下不使用缓存,看看还死机不
xuzhu3000 2010-10-20
  • 打赏
  • 举报
回复
Send次数多了会很慢。会卡
zhaohongbo83 2010-10-20
  • 打赏
  • 举报
回复
缓冲区是否满了是不用你判断的,底层协议这些都给我处理好了~
手机写程序 2010-10-19
  • 打赏
  • 举报
回复
服务器端先加sleep慢慢发过去看看是缓冲问题还是客户端有泄漏.
kang3252 2010-10-19
  • 打赏
  • 举报
回复
在每次send()的地方加上返回值的判断(异常判断),加上一点容错处理。死机也很有可能是你程序中哪里出现了死循环。我以前写通讯程序都不加判断发送或接收是否正常,也出现过死机!后来就是这里的问题!你看看你是不是同样的问题!
liwu12345 2010-10-19
  • 打赏
  • 举报
回复
你如果缓冲区满了,在send就不会存进缓冲区了,send的返回值表示你成功send了多少数据,你可以看看这个值是多少,还有你说的死机,我觉得可能是你的消息接受有误,接受的消息不正确,导致线程不能够及时释放CPU ,从而导致假死状态。你好好检查你的代码,看有这方面的问题没,还有可以在发送的消息前面加四字节的数据长度校验。。。。,可以试试!
傻X 2010-10-18
  • 打赏
  • 举报
回复
楼主,知道环形缓冲区么?这样缓冲区永远不会满,当然你代码也要处理好了,不然新的数据会把你没处理的缓冲区数据给覆盖了。
cheng_fengming 2010-10-18
  • 打赏
  • 举报
回复
你是运行一段时间内存才被耗尽的,那很应该就是在运行过程中不断的适用内存而没有释放吧,所以才好好看看程序吧,你可以在每次发送之后就及时的清空buffer,接受数据方用完也释放内存,看看有效果没。
向立天 2010-10-18
  • 打赏
  • 举报
回复
我觉得你怀疑的东西不是问题所在
底层协议如果连这点容错都做不到那TCP/IP协议是不是太脆弱了
你是不是有什么别的相关的位置申请了资源却没有及时释放
野男孩 2010-10-18
  • 打赏
  • 举报
回复
WireShark之类的工具抓包,然后看看链路上是不是有大量的零窗口出现
totti1006 2010-10-18
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 spiritmfc 的回复:]
1、怎么才能知道网络发送缓冲区是否已经满了?
2、如何知道网络发送缓冲区的空闲容量呢?


1。缓冲区慢了会send失败,再次空闲会调用FD_WRITE事件,可以根据这个进行推断是哪出了问题。
2。无法得知,这个是TCP算法决定的,你知道底层缓冲区多大?怎么个发送方法?它会拆成多少个小数据包?怎么个发送方法?恐怕看tcp/ip协议才知道。

错误排查需要你去单步调试 监控数据异常推断……
[/Quote]

我在程序里面可以这样吗?定义一个变量,BOOL m_bSend;当FD_WRITE消息到达的时候,m_bSend为TRUE;当在发送线程中send失败的时候,m_bSend为FALSE。在发送线程中判断m_bSend的值,如果为TRUE,就继续执行下面的发送函数;如果为FALSE,就continue,不执行下面的发送函数。
SpiritMFC 2010-10-18
  • 打赏
  • 举报
回复
1、怎么才能知道网络发送缓冲区是否已经满了?
2、如何知道网络发送缓冲区的空闲容量呢?


1。缓冲区慢了会send失败,再次空闲会调用FD_WRITE事件,可以根据这个进行推断是哪出了问题。
2。无法得知,这个是TCP算法决定的,你知道底层缓冲区多大?怎么个发送方法?它会拆成多少个小数据包?怎么个发送方法?恐怕看tcp/ip协议才知道。

错误排查需要你去单步调试 监控数据异常推断的。
没有一眼就能看出来的隐含错误;
totti1006 2010-10-18
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 spiritmfc 的回复:]
当缓冲区被填满了,再次空闲时 会调用FD_WRITE这个事件。
[/Quote]

如何知道缓冲区是否已经满了呢?
SpiritMFC 2010-10-18
  • 打赏
  • 举报
回复
当缓冲区被填满了,再次空闲时 会调用FD_WRITE这个事件。

totti1006 2010-10-18
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 visualeleven 的回复:]
你不会是因为其它分配的内存资源没有及时释放导致的吧。。。
[/Quote]
应该不是。

1、怎么才能知道网络发送缓冲区是否已经满了?
2、如何知道网络发送缓冲区的空闲容量呢?

如果我知道了前面的两个东西,再改一下程序就知道是不是你说的这个问题了
SpiritMFC 2010-10-18
  • 打赏
  • 举报
回复
底层缓冲区慢了,你send会失败的,所以内存耗尽应该和socket没啥关系。

应该是你程序代码本身的问题

在FD_WRITE里做个计数器 看看缓冲区是否正常释放了。

加载更多回复(1)

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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