茂名市网站建设_网站建设公司_营销型网站_seo优化
2026/1/16 9:10:33 网站建设 项目流程

在网络编程中,很多初学者会误以为:调用write就是把数据直接发到了网线上,调用read就是直接从网线上抓取数据。

事实并非如此。你的程序其实是在和操作系统的内核缓冲区打交道。

一、 核心机制:套接字中的文件描述符与缓冲区

当服务器通过accept建立连接,或客户端通过connect连接成功后,双方都获得了一个用于通信的文件描述符(File Descriptor)。

1. 两个 FD 的区别(服务器端)

  • 监听 FD (lfd)
    • 来源socket()->bind()->listen()
    • 作用:只负责在那“站岗”,通过accept()接受新的连接请求。
    • 读缓冲区:存储的是待处理的新连接请求(已完成三次握手)。
  • 通信 FD (cfd)
    • 来源accept()的返回值。
    • 作用:专门负责和某一个特定的客户端进行数据传输。
    • 读缓冲区:存储的是客户端发来的数据

2. 双向缓冲机制

每一个通信 FD在内核中都维护着两块内存区域:

  • 写缓冲区 (Write Buffer)
    • 当你调用write/send时,数据只是从应用程序被拷贝到了这个缓冲区。
    • 内核协议栈会在合适的时机(自动)将数据打包通过网络发送出去。
  • 读缓冲区 (Read Buffer)
    • 网卡收到的数据,由内核接收并存放在这里。
    • 当你调用read/recv时,你是从这里拿走数据。

TCP 的流式特性:正因为有缓冲区的存在,收发两端的数据量可以不对等

  • 例如:客户端每 5 秒发送 4KB 数据。
  • 服务器端:可以每秒读取 100 字节,只要缓冲区没溢出,数据就不会丢。

二、 函数对比:Read/Write vs Recv/Send

在 Linux 网络编程中,标准文件 IO 函数和 Socket 专用 IO 函数经常混用。

1. 接收数据

// 标准文件IOssize_tread(intfd,void*buf,size_tcount);// Socket专用ssize_trecv(intsockfd,void*buf,size_tlen,intflags);
  • 区别recv多了一个flags参数。
  • flags:通常设置为0。此时recv等同于read
  • 常用 flagMSG_PEEK(查看数据但不从缓冲区取出)、MSG_DONTWAIT(非阻塞模式)。

2. 发送数据

// 标准文件IOssize_twrite(intfd,constvoid*buf,size_tcount);// Socket专用ssize_tsend(intsockfd,constvoid*buf,size_tlen,intflags);
  • 同理,当flags为 0 时,send等同于write

三、 代码实战:使用 Recv/Send 实现数据传输

我们将编写一个简单的 Echo 服务器和客户端,演示recvsend的使用,以及connect的连接流程。

1. 服务器端 (server_recv.c)

服务器负责接收客户端发来的数据,并原样发回。

#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询