【问题标题】:Socket Send And Receive Buffer套接字发送和接收缓冲区
【发布时间】:2018-11-08 18:36:58
【问题描述】:

我试图了解 Socket-Send(Receive)-Buffer 的概念。我写了这些代码: 客户:

int client = socket(AF_INET, SOCK_STREAM, 0);
int s = getsockopt(client, SOL_SOCKET, SO_SNDBUF, &sendBuffSize, &len);
int status = connect(client, (struct sockaddr*)&addr, sizeof(struct sockaddr_in));
printf("The send buff size is : %d.\n", sendBuffSize);
char buf[100000];
int n, wn;
int fd = open("./1.txt", O_RDONLY);
while ((n = read(fd, buf, sizeof(buf))) > 0) {
    wn = write(client, buf, n);
    printf("Write %d bytes.\n", wn);
}

Server:我将连接的客户端设置为Non-block,并将这个客户端加入到epoll中。一旦客户端向服务器发送数据,我就让主线程进入休眠[十秒] .

char buf[8192];
sleep(10);
int rn;
while ((rn = read(events[i].data.fd, buf, sizeof(buf))) > 0) {
    printf("Read %d bytes.\n", rn);
}

客户端发送缓冲区大小为16384,服务器接收缓冲区大小为20000[setsockopt]。

书上说:如果socket发送缓冲区满了,客户端调用write函数会阻塞。

但我得到了结果 [Client] : Result

还有服务器: Result

问题:

  1. 接收缓冲区大小 + 发送缓冲区大小
  2. 为什么服务器读取 8192 + 6808 = 15000 字节而不是连续读取 8192 字节?

【问题讨论】:

  • 这是一个好奇的事情,还是您正在尝试设计一个实际上依赖于缓冲区大小的程序?
  • 感谢您的回复。我是初学者。我只是想了解socket缓冲区的概念,所以我写了这个程序来检查我是否真的理解它。但是结果让我感到困惑。
  • 我认为 Linux 在套接字缓冲区大小中包含每个数据包的一些开销。对于大多数编程,您需要知道 有一个套接字缓冲区,但确切的大小等是不可靠的。
  • 谢谢,我会记住的。

标签: c linux sockets networking tcp


【解决方案1】:
  1. 这里没有证据表明客户端写入没有阻塞。相反,除了最后一个之外,所有写入都是 100,000 字节的事实,当您用完输入时,表明它必须已阻塞,将所有数据传输到更小的套接字缓冲区.

  2. TCP 对通过线路发送的数据进行分段和 IP 打包。您无法控制该过程。在任何情况下,read() 可以传输从 1 到提供的计数的任意数量的字节,或者在非阻塞模式下向上传输零。它是流协议,而不是消息传递协议。没有其他保证任何个人read() 一次会返回多少。

【讨论】:

  • 谢谢回复,我只是好奇socket buffer的概念,想模拟书上的过程。但是结果和书上的不一样。
  • 什么结果和什么书不一样?为什么会这样?除非您运行完全相同的硬件和软件?
  • 这本书是 Unix Network Programming(Volume1,3rd),Section 2.11。我不知道为什么以及应该如何。我没有相同的硬件或软件,如果我无法获得正确的现象,我能做的就是记住这个概念。谢谢。
  • 重点是没有理由应该是一样的。每个硬件,每个操作系统,实际上每个连接都可以表现不同,仅受定义的操作语义的影响,其中不包括从 25 年前的教科书精确复制结果,就像这本一样无疑是。
猜你喜欢
  • 1970-01-01
  • 2013-02-16
  • 1970-01-01
  • 1970-01-01
  • 2010-11-09
  • 2021-03-15
  • 1970-01-01
  • 1970-01-01
  • 2014-05-10
相关资源
最近更新 更多