上网,查询
发现有人在csdn问“为什么我的send()函数不是阻塞式的??”
为什么?????
一个朋友的回答
阻塞并不是说直到你发送数据到对方机器才返回的意思,它是说把你要发送的数据放入发送缓冲后,就直接返回。而有些不是阻塞时,如发送缓冲区空间不够了,他就直接返回,而阻塞时会等待发送缓冲区有空间。
还有一次发一个12M的数据,不好吧。
我的回答
我也遇到了这个问题,查阅了一些资料,send的阻塞应该这样来看
你是公司的老板,socket是个文员
现在你要把一个buffer发送给A公司的老板,现在你跑到文员那,说我要发送一个buffer给A公司的老板。。。
出现的情况,
1,假设现在文员正空闲呢(缓冲区没有数据,或者缓冲区的数据大于你的buffer),然后文员说,交给我吧,你回去吧,这就是为什么马上返回的原因
2,假设现在文员手头有很多buffer没发呢,文员告诉你,你等着,我前面的还没有发完,你在这阻塞一会吧,等我发完了前面的,待我的缓冲大于你的buffer的时候再。。。。。。。。
应该就是这个意思,文员假设在规定时间内没有发送完成,应该回来告诉你发送失败的,只是这个我不知道怎么做
还查了网上的文章
int nZero=0;
setsockopt(socket,SOL_S0CKET,SO_SNDBUF,(char *)&nZero,sizeof(nZero));
记得以前有些朋友讨论过,socket虽然send成功了,但是其实只是发送到数据缓冲区里面了,而并没有真正的在物理设备上发送出去;而通过这条语句,将发送缓冲区设置为0,即屏蔽掉发送缓冲以后,一旦send返回(当然是就阻塞套结字来说),就可以肯定数据已经在发送的途中了^_^,但是这样做也许会影响系统的性能
最后这个解答也许是最好的结果哦
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
先看看在阻塞模式下send的表现吧(注意缓冲区的大小,我这里是16k)
1,发送一个小于16k的数据,send马上就返回了
也就说是,send把待发送的数据放入发送缓冲马上就返回了,前提是发送的数据字节数小于缓冲大小
2,发送一个大于16k的数据,send没有马上返回,阻塞了一下
send一定要把所有数据放入缓冲区才会返回,假设我们发32k的数据,当send返回的时候,有16k数据已经到达另一端,剩下16k还在缓冲里面没有发出去
在阻塞模式下
如果发送成功,返回的nBytes一定等于len
nBytes = send(m_socket,buf,len,0);
也就是在代码中循环发送其实是没有必要的
再看看在非阻塞模式下的情况吧
1,发送一个小于16k的数据,send马上返回了,而且返回的字节长度是等于发送的字节长度的,情况和阻塞模式是向相同的
2,发送一个大于16k的数据,send也是马上就返回了,返回的nByte小于待发送的字节数
来模拟一下实际情况,假设我们有32k的数据要发送,
第一次send,返回16384字节(16k),也就是填满了缓冲区
第二次send,在这之前sleep了1000毫秒,这段时间可能已经有5000字节从缓冲区发出,到达另外一端了,于是缓冲区空了5000字节出来,相应的,这次返回的是5000,表示新放入了5000字节到缓冲区
第三次send ,和第二次相同,又放了6000字节
最后一次send,放入了剩下的字节数,这个时候缓冲还是有数据的。
在发送大于16k数据的情况下,那个send发送循环就是必须的了。