为啥我在 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 发送的字符串中有奇怪的数据? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章
为啥我在使用 SDL2 的 C++ 中出现“无匹配令牌错误”?
Linux 通过gethostbyaddr()查找DNS信息,为啥运行结果出现segmentation fault(core dumped)