一个关于Socket缓冲区设置大小的问题

kolige 2008-06-03 04:51:15
基于Socket的数据传输中,如果是在本机上运行,我发现只要大一些的文件就无法传输成功,开始怀疑是缓冲区太小了,导致接收端的数据不断被重写,后来我通过Setsocketopt来设置,1024*1024*1024*50(设置成很大,是为了测试),结果还是不行,传输40M的东西都不能成功,我发送文件的时候是1024个字节当作一个数据内容来发送的,于是我就在每次send之后就Sleep(1),又可以发送成功,就是速度奇慢无比,每次都sleep太慢了,所以我想发送几个数据包后再sleep,所以加上以下控制段:
if(SleepTime == 40 )
{
Sleep(1);
SleepTime = 0;
}
可是这样发送又不成功了。

我的发送和接受都是开线程解决的。

现在想请教各位牛人,遇到这个问题有什么解决方法吗?还有一个问题就是为什么发送40次后再Sleep为什么又会失败?难道是同步问题?我试过减少为发送了10次就sleep,结果更厉害,直接出错了,错误是****不能写,估计是内存出错了。
...全文
12128 20 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
山知木 2012-10-25
  • 打赏
  • 举报
回复
顶个

我现在也有问题,就是怎么能让Windos任务管理器中的网络利用到50%以上啊。
现在write 4096×100*4个字节 要1.2秒钟啊。 = =|||
herocsz 2011-10-14
  • 打赏
  • 举报
回复
设置阻塞模式
yym955 2010-05-20
  • 打赏
  • 举报
回复
关注。。。
wuhuang95 2009-10-09
  • 打赏
  • 举报
回复
ding
yangkui_happy 2009-09-03
  • 打赏
  • 举报
回复
2楼的说
while(iNeedSend){
int iRet = send(sock,p,iNeedSend,0);
if(iRet <= 0) return;//小于0表示出错,等于0表示断开
p += iRet;
iNeedSend -= iRet;
}
等于0表示断开是错的吧,recv是等于0才表示断开.
不要别人怎么说都拿来发表,不确定的最好自己搞几行代码,写程序的人是懒不得的.
hibiscusjinjin 2008-06-05
  • 打赏
  • 举报
回复
我也遇到这个问题。。关注中。。
僵哥 2008-06-04
  • 打赏
  • 举报
回复
按照非阻塞就要丢包的话,那我们linux服务器上面都是使用的select非阻塞,那几十万的客户不全部都叫起来了?
僵哥 2008-06-04
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 ouygg 的回复:]
必须是阻塞方式才能接收完整,否则可能会丢包
[/Quote]
那说说看,如何会因为非阻塞模式丢包?丢包的原理是什么?
痞子酷 2008-06-04
  • 打赏
  • 举报
回复
必须是阻塞方式才能接收完整,否则可能会丢包
僵哥 2008-06-04
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 kolige 的回复:]
看来还是要仔细的看看TCP/IP协议

最后问一句,假如发送失败,是不是要自己在写程序的时候,写重发?

感谢unsigned的回答
[/Quote]
具体要看失败之后的错误号,然后依据需要判定是否需要重发。
Jikycc 2008-06-04
  • 打赏
  • 举报
回复
关注。。。
kolige 2008-06-04
  • 打赏
  • 举报
回复
看来还是要仔细的看看TCP/IP协议

最后问一句,假如发送失败,是不是要自己在写程序的时候,写重发?

感谢unsigned的回答
僵哥 2008-06-03
  • 打赏
  • 举报
回复
建议翻阅TCP/IP协议相关的书籍或文章,而不是某个人或几个人的回贴。另外就是基于异步消息通知的确实有可能会因为接收方过于缓慢地响应(中间处理过程过长)会导致通知的消息被丢弃,从而双方僵持着,接收方得不到read消息,发送方也发送不了。这个其实是应用程序编写所需要注意的问题,比如通过检查socket缓冲等等来解决。

早先刚学习网络开发的时候,使用TServerSocket/TClientSocket,就出现过类似的问题,当时也以为是需要sleep,也确实加一个sleep就可以收全消息。但是这个仅仅只是个人理解不够。如果每发几个几十个包就需要sleep一下,那么一秒钟能发多少个包?又如何来高速网络服务?比如使用完成端口(现在好象在windows下比较流行,这也与当前系统的全面支持分不开),每秒钟可以处理几万几十万个包。如果是需要sleep的话,就算以40个包sleep一个,那么一秒钟最精确就只是1000*40,那也才4万个包,而对于Sleep,目前在Window2k3当中,最精确也就15毫秒起,那么,就算只有5毫秒,那一秒钟也就只能是200次,也就才8000个包,

真正要做网络开发,个人比较建议还是从基础的API编程开始。这过程可能会碰到众多的问题,而随着问题被解决,对网络开发的了解和掌控也就加深,不管只是学习还是完成工作需要都是有极大好处的。
kolige 2008-06-03
  • 打赏
  • 举报
回复
刚刚看到一个类似的帖子:
用tcp,每发一次数据都sleep,否则对方收数据不完整,不管sleep时间多少,只要每发一次数据都sleep,就正常了。
请问这是为什么?

回复中:
我觉得应该是接收的缓冲区太小,发送的数据把接受缓冲区的数据覆盖掉了,这个和TCP数据完整没有什么关系,因为对方linux主机已经接受到数据了,而且返回了ack包,只是你的接受缓冲区太小,容纳不下这些数据。
sleep的话,减慢了速度,这样就不会导致linux主机的接收缓冲区被冲掉,但是会影响程序的效率
我觉得应该在linux那边的程序里面调用setsockopt函数,设置接受缓冲区大小,这样可能会好点。
呵呵,个人观点,不对的地方,请大家指教


帖网址是:
http://topic.csdn.net/u/20080602/11/c7b1d345-fcfc-44c0-b1bc-bce57b6046d7.html

请大家指教指教
kolige 2008-06-03
  • 打赏
  • 举报
回复
那为什么现在我只要在发送那个地方加一个Sleep就可以了呢?

只要不Sleep就不能成功接受完整的数据
僵哥 2008-06-03
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 kolige 的回复:]
现在不是我的程序有问题,我也制定了一套协议,我也知道TCP是流式的,问题是我现在接收端和发送端都在一台机子上,出现问题是因为发送端发送的数据速度很快,接收端的缓冲区不断的被重写,导致接收端没有接收到合适的数据。
具体说:发送端假如要发送10个数据包,假设每2秒发送1个数据包,而接收端有2个数据包大小的缓冲区
由发送端发送了1个数据包,存储在接收端的缓冲区内,5秒后发送端再发送1个数据包,然而接收端还没有去…
[/Quote]
对于TCP协议,当对端缓冲区满了之后,你是无法发送成功的。
kolige 2008-06-03
  • 打赏
  • 举报
回复
现在不是我的程序有问题,我也制定了一套协议,我也知道TCP是流式的,问题是我现在接收端和发送端都在一台机子上,出现问题是因为发送端发送的数据速度很快,接收端的缓冲区不断的被重写,导致接收端没有接收到合适的数据。
具体说:发送端假如要发送10个数据包,假设每2秒发送1个数据包,而接收端有2个数据包大小的缓冲区
由发送端发送了1个数据包,存储在接收端的缓冲区内,5秒后发送端再发送1个数据包,然而接收端还没有去取数据包,发送端又一次发了一个数据包,而缓冲区已经满了,所以覆盖了缓冲区的某些数据,对于TCP来说,数据已经接收到了,并没有出错,但是由于数据被覆盖了,所以接收端并没有接收到完整的数据。

这个也就解释了为什么我在Sleep之后,就可以接受完整的数据了。

或者我理解有错误,请牛人指导。
僵哥 2008-06-03
  • 打赏
  • 举报
回复
非特别需要的情况下,不要用Setsocketopt设置缓冲区大小,使用默认的就可以了,在Windows平台下默认8k已经足够了。最好最好的环境也就只支持到64k.
僵哥 2008-06-03
  • 打赏
  • 举报
回复
不管发送多大的数据,一定要注意判断send的返回值,这才是真正发送出去的字节数
需要记住的是任何一个带有返回值的function,其返回值都有一定的意义,除非你很明确不关心,一定要养成处理返回值的习惯,
char *Buf;
#define BUF_LEN 10*1024*1024//10MB
Buf = new char[BUF_LEN];//此时Buf当中都是随机数据,实际需要的话,自己填充

int iNeedSend = BUF_LEN;
char *p = Buf;
while(iNeedSend){
int iRet = send(sock,p,iNeedSend,0);
if(iRet <= 0) return;//小于0表示出错,等于0表示断开
p += iRet;
iNeedSend -= iRet;
}

delete[] Buf;
jxw1987628 2008-06-03
  • 打赏
  • 举报
回复
你用的控件还是socket函数?

数据按流发送,应该不会有问题啊

1,317

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder 网络及通讯开发
社区管理员
  • 网络及通讯开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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