read write recv send函数的区别

read,write和recv,send函数的功能,区别就是多了第四个参数。当第四个参数为0时,功能是一样的。
send用于使用tcp的套接字,提供了控制参数。write只是将套接字当成 了文件处理。建议使用 send
下文中的例子,读使用的是read,写使用的是send

read:ssize_t read(int fd,void *buf,size_t nbyte)
read函数是负责从fd中读取内容.当读成功 时,read返回实际所读的字节数,如果返回的值是0 表示已经读到文件的结束了,小于0表示出现了错误.如果错误为EINTR说明读是由中断引起 的, 如果是ECONNREST表示网络连接出了问题. 
返回的n是已经读取的,但是整体的数据内容不一定读取完毕。

read write recv send函数的区别_第1张图片

可以看出在该逻辑中,每次读取的最大值是64M(所以每次微信发消息都是有长度限制的。)怎么处理大于64M的情况呢?只能从产品逻辑上处理了。比如发送的消息内容不能多于64M。

write:ssize_t write(int fd, const void*buf,size_t nbytes)
write函数将buf中的nbytes字节内容写入文件描述符fd.成功时返回写的字节数.失败时返回-1. 并设置errno变量. 在网络程序中,当我们向套接字文件描述符写时有两可能.

1)write的返回值大于0,表示写了部分或者是全部的数据. 这样我们用一个while循环来不停的写入,但是循环过程中的buf参数和nbyte参数得由我们来更新。也就是说,网络写函数是不负责将全部数据写完之后再返回的

2)返回的值小于0,此时出现了错误.我们要根据错误类型来处理.
如果错误为EINTR表示在写的时候出现了中断错误.
如果为EPIPE表示网络连接出现了问题(对方已经关闭了连接).

read write recv send函数的区别_第2张图片

上图中代码的逻辑是,首先用p指针记录下了当前数据开始的指针:
[self.data bytes]

注释为:字节方法返回一个指针,指向由接收方管理的内存的连续区域。如果接收器所表示的内存区域已经是连续的,那么它在O(1)时间内就会这样做,否则可能会花费更长的时间使用-enumerateByteRangesUsingBlock:对于连续和不连续数据都是有效的。

根据SSL_write/write_data函数返回的n,p指针往后走n个字节。如果发送完毕,则将writeSource暂停。


read write recv send函数的区别_第3张图片

在该例子中,发送数据用的是send函数。下面是write和send函数的区别。
recv:int recv(int fd,void *buf,int len,int flags)
send: int send(int fd,void *buf,int len,int flags)
send比write多了第四个参数,第四个参数可以是0或者以下组合,如果是0,则功能就和write是一样的功能。

MSG_DONTROUTE:不查找表
 是send函数使用的标志,这个标志告诉IP,目的主机在本地网络上,没有必要查找表,这个标志一般用在网络诊断和路由程序里面。
MSG_OOB:接受或者发生带外数据, 表示可以接收和发送带外数据。
MSG_PEEK:查看数据,并不从系统缓冲区移走数据
是recv函数使用的标志,表示只是从系统缓冲区中读取内容,而不清楚系统缓冲区的内容。这样在下次读取的时候,依然是一样的内容,一般在有过个进程读写数据的时候使用这个标志。
 MSG_WAITALL:等待所有数据
是recv函数的使用标志,表示等到所有的信息到达时才返回,使用这个标志的时候,recv返回一直阻塞,直到指定的条件满足时,或者是发生了错误。

参考文章:https://www.cnblogs.com/ben-ben/articles/2812494.html
https://bbs.csdn.net/topics/30349499

你可能感兴趣的