在winsock中重用向量作为数组的更有效方法?

Posted

技术标签:

【中文标题】在winsock中重用向量作为数组的更有效方法?【英文标题】:More efficient way to reuse vector as array in winsock? 【发布时间】:2009-03-07 08:09:24 【问题描述】:

我目前使用向量作为 c 样式的数组通过 Winsock 发送和接收数据。

我有一个 std::vector,我将它用作我的“字节数组”。

问题是,我使用了两个向量,一个用于每个发送,一个用于每个接收,但我所做的似乎相当低效。

例子:

std::string EndBody("\r\n.\r\n");
std::fill(m_SendBuffer.begin(),m_SendBuffer.end(),0);
std::copy(EndBody.begin(),EndBody.end(),m_SendBuffer.begin());
SendData();

SendData 只是调用 send 适当的次数并确保一切正常。

无论如何。除非我在每次使用之前将向量归零,否则我会收到内容重叠的错误。有没有更有效的方法让我做我正在做的事情?因为似乎在每次调用时将整个缓冲区归零是非常低效的。

谢谢。

【问题讨论】:

发布 Send() 的代码 你到底想做什么? 【参考方案1】:

你可以使用 m_SendBuffer.clear()

否则 end() 方法将不知道缓冲区的实际大小。

clear() 不是一个非常昂贵的调用方法。除非你在做一些 486 或其他不应该影响你的表演的东西

【讨论】:

【参考方案2】:

似乎其他发帖人都在关注清除缓冲区的成本或缓冲区的大小。然而,您实际上并不需要清除或清零整个缓冲区,或者知道它的大小,因为您正在做的事情。 “内容重叠的错误”是 SendData 的问题,您尚未发布代码。大概 SendData 不知道它需要发送多少缓冲区,除非其中的数据是零终止的。如果这个假设是正确的,那么您所要做的就是正确地对数据进行零终止。

std::copy(EndBody.begin(),EndBody.end(),m_SendBuffer.begin());
m_SendBuffer[EndBody.size()] = 0;
SendData();

【讨论】:

【参考方案3】:

调用 clear 不是意味着向量的新大小为 0 吗?如果 OP 将向量用作一大块内存,那么他们必须在 clear 后调用 resize 以确保有适当的空间可用于调用 send 和 recv。

在向量上调用 clear 然后 resize 将与仅用零填充它大致相同,不是吗?

vector::clear

vector::resize

fill

【讨论】:

它不会改变向量的内存分配。这通常可以通过与临时空向量进行交换来减少。【参考方案4】:

据我了解the STL docs,调用 clear 只是将 .end() 值设置为与 .begin() 相同并将大小设置为零,这是即时的。

它不会改变分配的内存量或内存的位置(任何迭代器显然都是无效的,但数据往往会滞留!)。正如您已经发现的那样, .capacity() 不会改变,存储在那里的数据也不会改变。如果您总是使用 .begin() .end() 和 STL 迭代器来访问该区域,这无关紧要。

不要忘记,一个类的方法变量不会被初始化,除非你将它们包含在你的初始化列表中。添加m_SendBuffer(BUFSIZE,0) 可能会成功。

【讨论】:

以上是关于在winsock中重用向量作为数组的更有效方法?的主要内容,如果未能解决你的问题,请参考以下文章

使用犰狳访问下三角元素的更有效方法

使用 WinSock 客户端/服务器应用程序重用套接字

获取每个坐标的对角线长度的更有效方法

用元素加载 std::queue<uint8_t*> 的更有效方法?

如何将向量序列化为字符数组

在 SYCL 中使用一个缓冲区还是多个缓冲区更有效?