1.socket缓冲满了,就会将数据复制到内核缓冲向目标发送,然后socket缓冲又可以再接收更多数据,如果内核缓冲向目标发送数据速度很
快(马上完成,不存在网络阻塞等),那么从socket缓冲复制数据到内核缓冲,内核缓冲向目标发送,socket缓冲被清空再接收更多数据这个动作不存
在“阻塞”的话,那么就算发送更多数据也不会返回WSAWOULDBLOCK,内网一般是100Mbps,延迟小于10ms,不会出现数据阻塞情况一点不
奇怪,内网传输数据能到达10MB/S的速度呢。
2.FD_READ是只要接收缓冲中还有数据可以被接收,就会触发,不管有多少数据在接收缓冲.例如接收缓冲在8k数据,你用recv()接收了3k,还有5k在接收缓冲,还会有FD_READ继续触发。
3.不会出现WSAEWOULDBLOCK是不可思议的,就算在同一内网中发送和接收,也会出现WSAEWOULDBLOCK,我不知道你每次发送数据有多大,但只要每次发送超过4K的话,出现WSAEWOULDBLOCK是肯定的,除非本机给本机发。
2.
TCP和UDP都适用。将socket设成NONBLOCK(使用fcntl函数),然后select到该socket可读之后,使用read/recv来读取数据。当函数返回-1,同时errno是EAGAIN或EWOULDBLOCK的时候,表示数据已经全部读取完毕。
所以推荐使用第二种方法,第二种方法正确而且对TCP和UDP都管用。事实上,不论什么平台编写网络程序,我认为都应该使用select+NONBLOCK
socket的方式。这样可以保证你的程序至少不会在recv/send/accept/connect这些操作上发生block从而将整个网络服务都停下来。不好的地方就是不太利于Debug,如果是block的socket,那么GDB一跟就能知道阻塞在什么地方了。。。