『壹』 recv/send/recvfrom/sendto/recvmsg/sendmsg小结
总结网络编程中的recv与send:
使用read与write可对套接字进行读写,fd为套接字描述符,write复制buf数据至内核TCP缓冲区,具体数据传输时间由系统控制。
write阻塞发生在内核发送缓冲区满时,每个socket具有独立的接收与发送缓冲区。
在TCP中,recv与send用于精确控制数据传输,buf与len指定数据位置与大小,flags提供额外控制。
对于UDP,recvfrom与sendto常用,它们用于无连接通信,读取数据需获取发送端地址,写入数据需指定接收端地址。
recvfrom与sendto的flags与返回值与recv与send相同,用于TCP面向连接socket数据读写,使用NULL忽略地址参数。
通用数据读写函数通过msghdr结构体实现,包含接收或发送端地址与数据缓冲区。
msg_iov成员定义分散内存块,msg_iovlen指定块数量,实现分散读或集中写。
msg_control与msg_controllen用于辅助数据传输,具体用法可参考《linux高性能服务器编程》13.9部分。
recvmsg与sendmsg的flags字段含义与recv与send相同,影响读写过程与结果。
『贰』 recv/send/recvfrom/sendto/recvmsg/sendmsg小结
总结网络编程中recv/send与相关系统调用的用法。
使用read和write函数也可进行网络套接字读写,写入后数据暂存于内核TCP发送缓冲区,具体传输、接收及处理无保障。
write函数阻塞发生在内核socket发送缓冲区满时,每个socket拥有独立的接收与发送缓冲区。
在TCP上下文中,通常使用recv和send函数,send函数接收sockfd上的数据,buf和len参数指定位置和大小,成功返回实际写入长度,失败返回-1并设置errno。
flags参数增加额外控制,可取特定选项进行数据传输控制。
UDP读写采用recvfrom和sendto,recvfrom读取数据,接收端socket地址需获取,sendto指定接收端地址。
这两个系统调用的flags及返回值与send/recv函数类似,recvfrom/sendto用于面向连接socket时,设置最后两个参数为NULL。
通用数据读写函数,适用于TCP和UDP,sockfd指定目标socket,msg参数为msghdr结构体指针。
msghdr结构体包含msg_name、msg_iov、msg_iovlen、msg_control和msg_controllen、msg_flags成员。
msg_name指定通信对方socket地址,msg_iov指定分散内存块,msg_iovlen指定数量,用于分散读或集中写。
msg_control和msg_controllen用于辅助数据传输,msg_flags成员继承recvmsg/sendmsg flags参数,recvmsg结束前更新。
recvmsg与sendmsg函数的flags参数含义与send/recv函数一致。
『叁』 recv函数返回什么值
recv函数返回其实际的字节数,如果recv在时出错,那么它返回SOCKET_ERROR。如果recv函数在等待协议接收数据时网络中断了,那么它返回0。
扩展阅读,linux recv函数详解:
1 #include <sys/socket.h>
2 ssize_t recv(int sockfd, void *buff, size_t nbytes, int flags);
recv 的前3个参数等同于read函数。
flags参数值为0或:
flags
说明
recv
send
MSG_DONTWAIT
仅本操作非阻塞
MSG_OOB 发送或接收带外数据
MSG_PEEK
窥看外来消息
MSG_WAITALL
等待所有数据
recv函数解析:
sockfd: 接收端套接字描述符
buff: 用来存放recv函数接收到的数据的缓冲区
nbytes: 指明buff的长度
flags: 一般置为0
1) recv先等待s的发送缓冲区的数据被协议传送完毕,如果协议在传送sock的发送缓冲区中的数据时出现网络错误,那么recv函数返回SOCKET_ERROR
2)
如果套接字sockfd的发送缓冲区中没有数据或者数据被协议成功发送完毕后,recv先检查套接字sockfd的接收缓冲区,如果sockfd的接收缓
冲区中没有数据或者协议正在接收数据,那么recv就一起等待,直到把数据接收完毕。当协议把数据接收完毕,recv函数就把s的接收缓冲区中的数据
到buff中(注意协议接收到的数据可能大于buff的长度,所以在这种情况下要调用几次recv函数才能把sockfd的接收缓冲区中的数据
完。recv函数仅仅是数据,真正的接收数据是协议来完成的)
3) recv函数返回其实际的字节数,如果recv在时出错,那么它返回SOCKET_ERROR。如果recv函数在等待协议接收数据时网络中断了,那么它返回0。
4) 在unix系统下,如果recv函数在等待协议接收数据时网络断开了,那么调用 recv的进程会接收到一个SIGPIPE信号,进程对该信号的默认处理是进程终止。