我想我的问题很清楚。我正在阅读这篇文章以了解套接字是如何工作的,它提到了套接字和缓冲区这两个术语:
假设数据包是按顺序排列的,那么数据有效负载会被复制到套接字的接收缓冲区中。此时,内核将唤醒任何执行阻塞读取(2)的进程,或者使用诸如 select(2) 或 epoll_wait(2) 等 I/O 多路复用系统调用来等待套接字的进程。
这些术语的意思是一样的吗?如果有区别,那么区分套接字和缓冲区的是什么?
我想我的问题很清楚。我正在阅读这篇文章以了解套接字是如何工作的,它提到了套接字和缓冲区这两个术语:
假设数据包是按顺序排列的,那么数据有效负载会被复制到套接字的接收缓冲区中。此时,内核将唤醒任何执行阻塞读取(2)的进程,或者使用诸如 select(2) 或 epoll_wait(2) 等 I/O 多路复用系统调用来等待套接字的进程。
这些术语的意思是一样的吗?如果有区别,那么区分套接字和缓冲区的是什么?
套接字是比缓冲区更广泛的概念。一个套接字有两个缓冲区和一些与之相关的其他信息。
在套接字编程的上下文中,套接字是您的应用程序到一个 TCP 连接(或 UDP 流)的接口。您的应用程序不会直接从/向网络接口卡 (NIC) 读取/写入数据,它会通过内核的网络堆栈。套接字缓冲区是内核代表您的应用程序保存的数据包的短队列,因为它在 NIC 和您的应用程序的内存空间之间混洗数据。
发送缓冲区或写入缓冲区是您的应用程序已移交给网络堆栈以发送的数据包队列,而接收缓冲区或读取缓冲区是内核的网络堆栈代表您的应用程序接收的数据包队列,它正在等待您要读取的应用程序(也就是说,它存储在内核空间中,等待您的应用程序/进程要求将其复制到您的应用程序的内存中)。
在发送方,为了获得最佳性能,您的应用程序必须
write()
足够频繁地调用,并提供足够的数据,以确保内核的发送缓冲区永远不会用完要发送的数据。我们称之为“保持管道满”。但是为了最大限度地减少延迟,您的应用程序不应使用过多数据加载内核的发送缓冲区。在接收端,为了获得最佳性能,您的应用程序必须
read()
经常调用以尽量保持内核的接收缓冲区为空。否则,如果接收缓冲区没有足够的可用空间,网络堆栈将向发送者发出信号,告知其接收缓冲区已满,从而导致发送者减慢发送数据的速度。