我的客户端应用程序使用套接字作为http连接,意味着一次性发送、接收和关闭,我考虑每次使用单个持久连接,而不是单独的连接,但问题是,有时服务器收到2个32KiB的包,而单个64kiB的包,其他时候,有时甚至更小,所以为了弥补3次握手带来的延迟,我想启用TCP_FASTOPENTCP_NODELAY

我对客户端(connecting)套接字使用了setsockopt和这两个选项,但我对此感到困惑:

  • server side处,对于这两个选项,哪个插座为setsockopt、用socket函数创建的插座、或accept插座、或两者都是,
  • 此外,对于无意中分割数据分组(如2x32k或4x16k)而不是1x64k的问题,是否有任何解决方案

谢谢你

我阅读了Linux手册页中提供的文档,但发现它令人困惑

推荐答案

你处理这件事的方式错了.

TCP是一种流协议,因此不能保证一端对send的呼叫就会对应另一端对recv的呼叫.例如,您可以拨打send一次,然后必须拨打recv两次才能获得所有内容,或者您可以两次拨打send,然后在单个recv中阅读所有内容.

您的协议需要某种方法来确切知道要读取多少数据.如果您实际使用的是HTTP,这是内置在协议中的,即读取由回车符/换行符分隔的标题行,即\r\n后跟一个空行,后跟一个由Content-Length标题指定大小的正文.

如果您不使用HTTP,您可以做一些简单的事情,比如首先发送4个字节的数据长度,然后发送那么多字节的数据.

在这两种情况下,您将尽可能多地使用recv个字节,如果协议指示有更多的数据,则再次使用recv个字节.您还需要注意这样的情况:您已经读完了一条完整的消息,但缓冲区中读入的数据更多,这表明您需要开始处理另一条消息.

无论是否每次都建立新的连接,您都需要完成所有这些操作,因此您不妨将连接保持打开状态,而不必担心套接字选项.

C++相关问答推荐

当main函数调用被重构时,C函数给出错误的结果

如何在C中从函数返回指向数组的指针?

Make Node函数.S有什么问题吗?

Flose()在Docker容器中抛出段错误

是否可以通过调用两个函数来初始化2D数组?示例:ARRAY[STARTING_ROWS()][STARTING_COLUMNS()]

在C中访问数组中的特定值

处理来自浏览器的HTTP请求

我在反转双向链表时遇到问题

初始成员、公共初始序列、匿名联合和严格别名如何在C中交互?

条件跳转或移动取决于未初始化值(S)/未初始化值由堆分配创建(Realloc)

将数字的每一位数平方,并使用C将它们连接为一个数字(程序不能正确处理0)

如何使用空元素块声明指针数组

如何在C宏定义中包含双引号?

在下面的C程序中,.Ap0是如何解释的?

Tcl_GetDoubleFromObj在列表的迭代中是一个缺点

如何使crc32的结果与cksum匹配?

模仿 memmove 的行为

如何确保 gcc + libc 对于多字节字符串使用 UTF-8,对于 wchar_t 使用 UTF-32?

计算 e^x 很好.但不是 x 的罪

单线程代码中的编译器屏障是否必要?