Socket send函数和recv函数详细求解1.send函数
intsend(sockets,constcharFAR*buf,intlen,intflags );
无论是客户端还是服务器APP应用程序,都使用send函数将数据发送到TCP连接的另一端。 客户端通常使用send函数向服务器发送请求,服务器通常使用send函数向客户端发送响应。
此函数的第一个参数指定发送方套接字描述符。
第二个参数表示存储APP应用程序发送的数据的缓冲区
第三个参数指示实际发送的数据的字节数。
第四个参数通常设定为0。
这里只说明同步套接字send函数的执行流程。 调用此函数时,
1 ) send首先把要发送的数据的长度len与套接字s的发送缓冲区的长度进行比较,在len大于s的发送缓冲区的长度时,该函数返回SOCKET_ERROR;
2 )如果len小于s的发送缓冲区长度,send首先检查协议是否正在发送s的发送缓冲区的数据,等待协议发送完数据。 如果协议还没有开始发送s的发送缓冲区中的数据,或者s的发送缓冲区中没有数据,则send将s的发送缓冲区的可用空间与len进行比较
)3)如果len比剩馀空间的大小大,send就会继续等待协议发送完s的发送缓冲器中的数据
)4)如果len小于可用空间,send只是将buf中的数据复制到可用空间(请注意,send传递的是协议,而不是s发送缓冲区中的数据传递到连接的另一端。 send只是将buf的数据复制到s的发送缓冲区的可用空间中。
如果send函数的copy数据成功,则返回实际的copy字节数;如果send在copy数据中发生错误,则send返回SOCKET_ERROR; 如果在等待协议传输数据时网络断开,send函数会返回SOCKET_ERROR。
请注意,在send函数成功将buf中的数据复制到s发送缓冲区的剩馀空间之后,它会返回。 但是,此时,这些数据并不一定会立即传递到连接的另一端。 如果在后续传输过程中协议出现网络错误,以下套接字函数将返回SOCKET_ERROR。 (每个非send套接字函数在执行之前都必须等待协议传输套接字发送缓冲区中的数据,如果在等待过程中出现网络错误,套接字函数将返回SOCKET_ERROR。)
注:在Unix系统上,如果send在等待协议发送数据时断开与网络的连接,则调用send的进程将接收SIGPIPE信号,并且该信号的缺省进程将终止
测试表明,异步套接字的send函数可以在网络断开后立即返回适当的字节数。 也可以使用select检测进行写入,但几秒钟后send会出错并返回-1。 select也无法检测到可写。
2. recv函数
intrecv(sockets,charFAR*buf,intlen,intflags );
无论是客户端还是服务器APP应用程序,都使用recv函数从TCP连接的另一端接收数据。 此函数的第一个参数指定接收套接字描述符。
第二个参数表示存储recv函数接收的数据的缓冲区。
第三个参数表示buf的长度。
第四个参数通常设定为0。
这里只说明同步套接字recv函数的执行流程。 当APP应用程序调用recv函数时,
)1) recv先等待通过协议传输s的发送缓冲器中的数据,当协议在传输s的发送缓冲器中的数据时发生网络错误时,recv函数返回SOCKET_ERROR。
2 )在s的发送缓冲区没有数据或通过协议成功发送数据之后,recv检查套接字s的接收缓冲区,并且如果s的接收缓冲区没有数据或协议已经接收到数据,则recv进行操作协议接收完数据后,recv函数将s的接收缓冲区的数据复制到buf。 (因为协议接收到的数据有可能比buf的长度大,所以要注意在这种情况下要调用recv函数几次将s的接收缓冲区的数据复制完毕。 recv函数只有copy数据,真正的接收数据是通过协议完成的。)。
recv函数返回实际copy的字节数。 如果在复制期间recv出错,则返回SOCKET_ERROR; 如果网络在等待协议接收数据时中断,recv函数将返回0。
注:在Unix系统上,如果recv函数在等待协议接收数据时断开网络连接,则调用recv的进程将接收SIGPIPE信号,并且该进程的缺省处理过程将终止。