int send(SOCKET s, const char *buf, int len, int flags);
该函数在调用的时候,首先检测数据长度len与s关联的发送缓冲区的长度,如果len的长度大于发送缓冲区的长度,函数会返回报错SOCKET_ERROR,这个时候数据就要截断一段段的发送。如果len<=s缓冲区的长度,那么send先检查协议是否正在发送s的发送缓冲区数据。
如果发送缓冲区的数据正在发送就等待期发送完再发送该数据。
如果发送缓冲区的数据没开始发送就检测缓冲区剩余的长度能不能装得下len长度数据,如果len>剩余缓存区长度则send就等待,等待缓冲区数据被发送出去之后能容得下len长度了再把buf数据copy过来。如果ken<=剩余缓冲区长度则直接把buf拷贝到发送缓冲区里。【send仅仅是把数据copy到发送缓冲区里,并不是直接就发走了,发送是协议发送,send函数只是实现数据的copy而已】。如果send函数copy成功就返回成功字节数,否则返回SOCKET_ERROR.如果网络中断会收到一个SIGPIPE信号。
int recv (SOCKET s, char* buf ,int len, int flags);
该函数在调用时候先检查s缓冲区发送数据是否被协议发送完毕,如果没有先等待数据被发送,出错返回SOCKET_ERROR.
如果S缓冲区没有待发送的数据,或者发送成功,recv就检测s接收缓冲区的情况:
如果协议正在接受,函数就等待接收完毕之后recv就把数据copy到buffer变量中,如果没有数据就一直等待。当copy数据时候很有可能数据的长度会超出buf的长度len,这时候就需要循环几次去读去接受的数据。recv函数也仅仅是copy就是把数据从接收缓冲区copy到buf中。真正接受的过程也是由协议做的。如果recv在copy中出错,返回SOCKET_ERROR,否则如果在等待协议接收数据时候网络中断了,进程会收到一个SIGPIPE信号。
问:为什么recv函数时候要检测发送数据缓冲区,等发送数据缓冲区没有准备发送的数据之后再检测接收数据缓冲区?