为什么套接字读取的数据比实际发送的数据多? [英] Why do a socket reads more data than what is actually sent?

查看:33
本文介绍了为什么套接字读取的数据比实际发送的数据多?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个客户端和一个服务器,它们都是用 C 编写的,并且在 Linux 上运行.客户端请求数据段并向服务器发送相似的数据段.以下是客户端和服务器之间的典型交互.

I have a client and a server both written in C and running on Linux. The client requests data segments and sends similar data segments to the server. Here are the typical interactions between the client and the server.

  1. 客户端告诉服务器保存一些数据(即写请求).该请求由 4KB 的数据和少量额外的元数据字节(2xunsigned long + 1xint)组成.服务器保存数据,不响应写入请求.
  2. 客户端从服务器请求数据(即读取请求).请求由几个字节的元数据组成(再次...... 2xunsigned long + 1xint).服务器仅使用 4KB 数据段进行响应.

服务器端的跟踪显示它总是发送4KB的数据段.然而,客户端的跟踪显示了一个不同的故事:不同大小的数据包.如果在某一时刻客户端收到的数据大小不是 4KB,那么接下来的数据包加起来为 4KB 或 8KB.

The trace at the server side shows that it always sends 4KB data segments. However, the trace at the clients shows a different story: packets of different sizes. If at one point the client receives data of size other than 4KB then the following packet add up either to 4KB or 8KB.

为了说明错误模式,这里是我在跟踪中看到的一些示例:

To illustrate the faulty pattern here are some examples I saw in the trace:

  • 4KB、1200 字节、2896 字节、4KB.
  • 4KB、1448 字节、6744 字节、4KB.

我大概可以通过等待读取完整的 4KB 段来处理应用程序级别的第一种情况(即 1200B+2896B),但我不知道如何处理其他情况.但是,我宁愿完全避免整个问题并强制客户端/服务器接收每个 4KB 的完整数据段.

I can probably deal with the first scenario (i.e. 1200B+2896B) at the application level by waiting for a complete 4KB segment to be read, but I do not know how to deal with the other. However, I would rather avoid the whole issue altogether and force the client/server receive full data segments of 4KBs each.

我已经尝试禁用 Nagle 算法 (TCP_NODELAY) 并将 MTU 大小设置为 4KB.但这些都没有解决问题.

I have already tried disabling Nagle algorithm (TCP_NODELAY) and setting the MTU size to 4KB. But neither one of those solved the issue.

推荐答案

为什么套接字读取的数据比实际发送的数据多?

Why do a socket reads more data than what is actually sent?

它没有.它读取任何可用的数据,必要时在没有数据时阻塞.

It doesn't. It reads whatever data is available, after blocking if necessary while there is none.

你的问题是基于一个谬论.TCP 协议规范或 Berkeley Sockets API 中的任何地方都无法保证一次读取 == 一次写入.TCP是字节流协议.如果到达的数据多于您的预期,并且您提供给 recv() 或 read() 方法的缓冲区中有足够的空间,您将获得它.如果您想要消息边界,则完全由您来实现.

Your question is founded on a fallacy. There is no guarantee anywhere in the TCP protocol specification or the Berkeley Sockets API that one read == one write. TCP is a byte stream protocol. If more data arrives than you are expecting and there is enough room in the buffer you provide to the recv() or read() method, you will get it. If you want message boundaries it is strictly up to you to implement them.

这篇关于为什么套接字读取的数据比实际发送的数据多?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆