
本文共 1284 字,大约阅读时间需要 4 分钟。
HTML被重去除
1.send 函数
int send(SOCKET s, const char *buf, int len, int flags);
不论是客户端还是服务器应用程序都使用send函数向TCP连接的另一端发送数据。客户程序通常使用send函数向服务器发送请求,而服务器则使用send函数向客户程序发送回复。
该函数的第一个参数指定发送端套接字描述符。第二个参数指定要发送的数据缓冲区。第三个参数指定要发送的数据的字节数。第四个参数通常置0。
关于同步socket的send函数执行流程:
send首先检查要发送的数据长度len与套接字s的发送缓冲长度。如果len大于发送缓冲区长度,send返回SOCKET_ERROR。
如果len小于等于发送缓冲区长度,send检查协议是否正在发送套接字s的发送缓冲区中的数据。如果已经在发送且没有完成,send进入等待状态。若协议没有开始发送或发送缓冲区为空,send比较发送缓冲区的剩余空间大小与len。
如果len大于剩余空间大小,send一直等待协议将套接字发送缓冲区的数据发送完毕。
若len小于剩余空间大小,send仅将buf中的数据复制到发送缓冲区的剩余空间中(注意send不是直接将套接字发送缓冲区的数据发送到另一端的,而是预留给协议传输,send只是将buf数据复制到缓冲区)。
成功复制数据时send返回实际复制的字节数,若复制过程中发生错误send返回SOCKET_ERROR。若在等待协议传输时网络断开,send返回SOCKET_ERROR(在Unix系统中进程终止)。
异步socket的send函数在网络断开时仍可成功返回字节数,但随后会报错。select检测也无法检测到可写状态,需过几秒后再调用send才会出错。
2.recv函数
int recv(SOCKET s, char *buf, int len, int flags);
不论是客户端还是服务器应用程序都使用recv函数从TCP连接另一端接收数据。第一个参数指定接收端套接字描述符。第二个参数指定接收数据的缓冲区。第三个参数指定缓冲区长度。第四个参数通常置0。
关于同步socket的recv函数执行流程:
recv首先等待套接字s的发送缓冲区数据被协议成功传输完毕。在协议传输过程中如果发生网络错误 recv返回SOCKET_ERROR。
若发送缓冲区为空或已发送完毕,recv检查套接字接收缓冲区。若接收缓冲区为空且协议正在接收,recv进入等待,但若协议已完成接收,recv开始将数据复制到指定buf中(注意:协议接收的数据可能超过buf长度,此时需多次调用recv才能完全接收)。
成功复制时返回实际复制字节数。复制过程中发生错误返回SOCKET_ERROR。如果在等待协议接收数据时网络断开,recv返回0(在Unix系统中进程终止)。
注意事项:
- 在Unix系统中,网络断开导致recv返回0且进程终止。
- 异步socket的recv函数在网络断开时可返回数据,但随后会报错。
- select检测无法检测网络断开。
发表评论
最新留言
关于作者
