为啥 sys socket recv 函数不填充数据但返回字节长度?
Posted
技术标签:
【中文标题】为啥 sys socket recv 函数不填充数据但返回字节长度?【英文标题】:why sys socket recv function don't fill data but return bytes length?为什么 sys socket recv 函数不填充数据但返回字节长度? 【发布时间】:2018-06-14 09:16:11 【问题描述】:我正在编写一个 C++ 客户端。客户端通过 TCP 协议成功连接到服务器并发送数据。我写了下面的代码来接收数据:
char data[9];
int received_size = recv(fd, data, 9, flags);
std::string str data ;
// str.empty() is true
哪些标志是 MSG_NOSIGNAL。
问题是这行执行后received_size为9但数据长度为零。
【问题讨论】:
你如何确定数据的长度?您是否(错误地)使用 C 字符串或在第一个空字节处停止的类似函数来确定长度? @PaulMcKenzie 在这种状态下我知道我的服务器发送的数据包的长度。我想知道 recv 函数这种奇怪行为的原因 你没有回答我的问题。您如何确定(在代码中)数据为“空”? @PaulMcKenzie 问题代码已更新。 嗯,您的最新编辑回答了这个问题。你停在第一个空字节。接受指针的std::string
的构造函数就是这样做的。所以你的观察是不正确的。
【参考方案1】:
如果recv
正在返回一个值,那么这就是接收到的字节数。
问题在于您使用了错误的函数来确定您收到的数据。无论recv
返回的实际字节数如何,您正在使用的std::string
构造函数将在第一个空字节处停止。
改为使用其他版本的 std::string
构造函数,它采用字节长度:
char data[9];
int received_size = recv(fd, data, 9, flags);
std::string str(data, received_size);
【讨论】:
【参考方案2】:您期望接收到的数据是零终止的。这是一个错误的期望,因为它可以接收不完整的数据。正确的方法是使用received_size
(错误检查后):
std::string str(data, received_size);
这在实际应用中仍然不够。你需要delimit messages somehow。
【讨论】:
【参考方案3】:如果需要处理零字节,请使用std::vector<unsigned char>
而不是std::string
:
char data[9];
int received_size = recv(fd, data, 9, flags);
std::vector<unsigned char> str( std::begin(data), std::begin(data)+received_size );
std::cout << str.size() << '\n';
【讨论】:
以上是关于为啥 sys socket recv 函数不填充数据但返回字节长度?的主要内容,如果未能解决你的问题,请参考以下文章
Socket编程时recv函数错误:Transport endpoint is not connected的解决
C语言 recv()函数recvfrom()函数recvmsg()函数