read,send,write,recv的区别

本文介绍了在Unix系统中使用socket进行数据通信时,不同操作标志(如MSG_DONTROUTE、MSG_OOB等)的作用及意义,并指出当flags设置为0时的操作行为与read/write相同。此外还提到了可以利用read函数来读取socket数据。

______________________________________________

| MSG_DONTROUTE | 不查找路由表 |

| MSG_OOB | 接受或发送带外数据 |

| MSG_PEEK | 查看数据,并不从系统缓冲区移走数据 |

| MSG_WAITALL | 等待任何数据 |

|————————————————————–|

    如果flags0则和read,write一样的操作。

2、在unix中,所有的设备都可以看成是一个文件,所以我们可以用read来读取socket数据。

参考

【1】 http://apps.hi.baidu.com/share/detail/137478

2】 设置非阻塞

http://www.ajaxstu.com/Cbiancheng/107652.html

3】 http://blog.163.com/solylee@126/blog/static/17182315720111161368585/

4http://blog.163.com/clevertanglei900@126/blog/static/111352259201122001933162/

5】 http://topic.youkuaiyun.com/u/20090703/20/36925146-0f73-47fe-8a71-45ec245166ba.html

<think> 嗯,用户想了解RDMA中send/recvread/write区别。这个问题涉及RDMA的核心通信机制,需要结合系统级要求和引用内容来解答。 用户提供了两份引用资料,其中引用[1]提到RDMA Write需要提前交换内存地址和密钥,而send/recv也可以用于交换这些信息。引用[2]则详细说明了WR(工作请求)的结构差异,指出不同操作需要携带不同的参数。这些正好能支撑技术点的解释。 考虑到用户可能是RDMA初学者,需要先明确基本概念:send/recv是双端操作,依赖接收方准备缓冲区;而read/write是单端操作,请求方直接访问对端内存。这个根本差异会导致四种操作在流程、性能和应用场景上的不同。 准备重点对比三个维度:一是通信模型(双端vs单端),二是内存访问权限(send/recv无需对方内存权限但read/write需要),三是性能特征(零拷贝带来的优势)。特别是内存权限这点,引用[1]提到的"交换缓存地址和密钥"正是read/write操作的关键前置条件。 注意到用户上次提问涉及RDMA基本操作类型,这次明显想深入理解机制差异。回答时要避免陷入代码细节,而是用对比表格和流程示意图来呈现本质区别。性能对比部分需要强调read/write的零拷贝特性如何减少CPU干预,这对HPC场景很重要。 相关问题设计要引导用户走向实践层面:包括API使用差异(如ibv_post_send的参数配置)、错误处理(引用[2]提到接口会返回错误WR指针)、以及具体场景选择(如何时用write代替send)。最后补充语义差异的问题,因为像atomic这类操作其实属于write的变种。 </think> 以下是RDMA中Send/RecvRead/Write操作的核心区别对比: | **特性** | **Send/Recv** | **Read/Write** | |------------------|-------------------------------------------|-------------------------------------------| | **通信模型** | 双端协作(发送方+接收方) | 单端主动(请求方直接操作对端内存) | | **操作方向** | Send推数据 → Recv收数据 | 本地主动读取/写入远端内存 | | **内存权限要求** | 接收方仅暴露**接收缓冲区** | 需**显式暴露目标内存**(地址+rkey)[^1] | | **工作流程** | 1. 接收方预提交Recv WR<br>2. 发送方提交Send WR | 单方直接操作(无需对端实时响应) | | **CPU参与度** | 接收方需处理接收中断(可选轮询) | **完全零拷贝**(双方CPU均不感知数据传输) | | **API调用** | `ibv_post_send()`(SEND)/`ibv_post_recv()` | `ibv_post_send()`(READ/WRITE类型) [^2] | | **典型应用** | 消息传递、控制信令交换 | 大数据块传输、内存同步 | ### 关键区别详解 1. **内存访问权限** - **Send/Recv**:接收方通过注册MR(内存区域)提供缓冲区,但**不暴露具体地址**。通信时由接收方主动下发Recv WR指定接收位置。 - **Read/Write**:必须预先交换**远端内存地址+rkey**(通过Send或外部通信),写入方/读取方直接操作对端内存[^1]。 2. **零拷贝特性** - **Read/Write**实现**真·零拷贝**:本地网卡直接读写远端内存,双方CPU全程不参与数据传输。 - **Send/Recv**在接收端仍有内存拷贝:数据到达后需从网卡缓冲区复制到应用指定的Recv缓冲区。 3. **工作请求(WR)结构差异**[^2] ```c // READ/WRITE操作的WR需携带远端参数 struct ibv_sge { uint64_t addr; // 本地内存地址 uint32_t length; // 数据长度 uint32_t lkey; // 本地MR密钥 }; struct ibv_send_wr { // ... uint32_t opcode; // IBV_WR_RDMA_READ / IBV_WR_RDMA_WRITE uint64_t remote_addr; // 远端内存地址 uint32_t rkey; // 远端MR密钥 }; ``` *Send操作只需本地SGE,无需`remote_addr`和`rkey`。* ### 通信过程对比 **Send/Recv流程** ```mermaid sequenceDiagram 参与者A->>参与者B: 交换QPN、GID等连接信息 Note right of B: 预提交Recv WR 参与者A->>网卡A: Post Send WR (数据+目标QPN) 网卡A->>网卡B: 通过RNIC直传数据 网卡B->>参与者B: 数据存入Recv缓冲区并触发完成事件 ``` **Write流程** ```mermaid sequenceDiagram 参与者A->>参与者B: 通过Send交换远端内存地址+rkey 参与者A->>网卡A: Post Write WR (数据+远端地址/rkey) 网卡A->>网卡B: 通过RNIC直写数据到B的内存 网卡B->>参与者B: 无通知(除非配置完成事件) ``` ### 性能与应用场景 | **操作** | 延迟 | 吞吐量 | 典型场景 | |-------------|------|--------|----------------------------------| | **Write** | ★★★☆☆ | ★★★★★ | 大数据推送(如机器学习参数更新) | | **Read** | ★★☆☆☆ | ★★★☆☆ | 远程数据拉取(如分布式数据库查询)| | **Send** | ★★★★★ | ★★★☆☆ | 控制消息、小数据交互 | > **关键结论**:需高频传输大数据时优先选用Write(避免接收方CPU瓶颈),而Send/Recv更适合协调交互场景。实际应用中常组合使用,例如**先用Send交换元数据,再用Write传输主体数据**[^1]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值