send函数特点及相关问题

来源:互联网 发布:mac 命令 alias 编辑:程序博客网 时间:2024/05/17 08:05

在send函数的help里面看到

The successful completion of a send call does not indicate that the data was successfully delivered.
send成功完成并不代表数据已经成功送达。

If no buffer space is available within the transport system to hold the data to be transmitted, send will block unless the socket has been placed in nonblocking mode.
如果没有缓冲存储待发送的数据,send会阻塞直到socket被设置为非阻塞模式,
On nonblocking stream-oriented sockets, the number of bytes written can be between 1 and the requested length, depending on buffer availability on both client and server machines.
在非阻塞流模式socket中,写入的字节可以是1到需要的长度,依赖于客户端和服务器的缓冲。
The select or WSAEventSelect function can be used to determine when it is possible to send more data.
select 或 WSAEventSelect 函数可以用于决定什么时候可以继续发送数据


阻塞模式下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发送循环就是必须的了

[Ref Link]http://www.cppblog.com/artmouse/archive/2005/12/14/1762.aspx

原创粉丝点击