为啥我在 C++ 中使用 socket.h 通过 Internet 发送的字符串中有奇怪的数据? [关闭]

Posted

技术标签:

【中文标题】为啥我在 C++ 中使用 socket.h 通过 Internet 发送的字符串中有奇怪的数据? [关闭]【英文标题】:Why is there weird data in strings I send over the internet using socket.h in C++? [closed]为什么我在 C++ 中使用 socket.h 通过 Internet 发送的字符串中有奇怪的数据? [关闭] 【发布时间】:2014-08-15 03:57:37 【问题描述】:

注意:如果我看起来很无知,请耐心等待,我是C++的网络编程新手。

每当我使用socket.h 通过C++ 中的连接发送数据时(当我在Windows 上使用winsock 时也会发生),我在发送的任何内容的末尾都会收到随机数据。

例如,如果我尝试让客户端将"Hello" 发送到服务器,然后让服务器打印出它收到的任何内容,它将以"Hello�%" 或类似的形式出现。这是因为我通过 Internet 发送它,还是与我打印它的方式有关(可能缺少空终止符)。

如果它在发送时拾取随机数据,那将是一个问题,因为我可能会写一些可以下载文件或类似的东西,这显然会干扰。我相当确定它缺少空终止符或其他内容,但尝试在末尾添加 '\0' 并没有做任何事情。另请注意,数据存储在 C-Style 字符串中。

这是发送数据的代码:

send(sock, (char*)"Hello", strlen("Hello"), 0);

这是接收代码:

char recvbuf[100];
int len = strlen(recvbuf);
recv(sock, recvbuf, len, 0);
cout << recvbuf << endl;

【问题讨论】:

问题可能是您未能发送和/或读取 nul 终止符。除非您发布演示问题的代码,否则我们无法确定。 邮政编码显示您如何发送/接收消息和您的字符数组。 I -1 这是因为它不包含可重现的代码,这意味着我们只能推测。 将字符串的每个字符打印为十六进制或十进制值。这应该可以让您更好地了解奇怪的字符。 @simonc - 我添加了我正在使用的代码。 【参考方案1】:
send(sock, (char*)"Hello", strlen("Hello"), 0);

发送strlen("Hello") 字节,即 5 个字节,没有 nul 终止符。

char recvbuf[100];
int len = strlen(recvbuf);
recv(sock, recvbuf, len, 0);

通过读取未初始化的数组来寻找终止符来调用未定义的行为。您可能会阅读超出分配内存的末尾。您几乎肯定不会正确地将 len 分配给 100。

作为一个非常快速的修复,您可以将代码更改为

const char* str = "Hello";
send(sock, str, strlen(str)+1, 0);

char recvbuf[100];
int len = recv(sock, recvbuf, sizeof(recvbuf), 0);

请注意,这仍然不安全。无法保证recv 将在一次调用中读取多少字节。为了使您的代码健壮,您需要定义一个简单的协议(例如)使用消息的前 2 个字节来指定后面的字节数,或者更改您的客户端以重复读取,附加到 recvbuf 直到它找到空终止符。

【讨论】:

【参考方案2】:

strlen("Hello")5。当你想发送 6 个字节时,你正在发送 5 个字节。

更改您的代码以考虑终止字节。

send(sock, (char*)"Hello", strlen("Hello") + 1, 0);

【讨论】:

以上是关于为啥我在 C++ 中使用 socket.h 通过 Internet 发送的字符串中有奇怪的数据? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

为啥我在 C++ 阶乘函数中出现编译错误?

为啥我在使用 SDL2 的 C++ 中出现“无匹配令牌错误”?

为啥程序不在main中执行打印语句?

Linux 通过gethostbyaddr()查找DNS信息,为啥运行结果出现segmentation fault(core dumped)

为啥通过 system("color YX") 在 C++ 控制台应用程序中更改颜色不是最佳解决方案?

为啥当我在 MD5 哈希中转换相同的 C++ 字符串时,每次都会获得不同的输出?