c++ - 缓冲区套接字末尾的垃圾
问题描述
当我5
通过串行终端发送时,recv()
输出发送的数据,然后是损坏的垃圾(5╠╠╠╠╠╠╠╠☺0
)。这是我的代码:
#include <winsock2.h>
#include <ws2bth.h>
#include <Windows.h>
#include <iostream>
#include <string.h>
#pragma comment(lib, "Ws2_32.lib")
using namespace std;
int i;
unsigned int aaddr[6];
void send2(string in) {
WSADATA wsa;
memset(&wsa, 0, sizeof(wsa));
int error = WSAStartup(MAKEWORD(2, 2), &wsa);
SOCKET btSocket = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
SOCKADDR_BTH sockAddr;
memset(&sockAddr, 0, sizeof(sockAddr));
sockAddr.addressFamily = AF_BTH;
sockAddr.serviceClassId = RFCOMM_PROTOCOL_UUID;
sockAddr.port = BT_PORT_ANY;
BTH_ADDR tmpaddr = 0;
sscanf_s("7C:9E:BD:4C:BF:B2", "%02x:%02x:%02x:%02x:%02x:%02x", &aaddr[0], &aaddr[1], &aaddr[2], &aaddr[3], &aaddr[4], &aaddr[5]);
*&sockAddr.btAddr = 0;
for (i = 0; i < 6; i++) {
tmpaddr = (BTH_ADDR)(aaddr[i] & 0xff);
*&sockAddr.btAddr = ((*&sockAddr.btAddr) << 8) + tmpaddr;
}
connect(btSocket, (SOCKADDR*)&sockAddr, sizeof(sockAddr));
char charIn[28];
strcpy_s(charIn, in.c_str());
send(btSocket, charIn, (int)strlen(charIn), 0);
closesocket(btSocket);
}
void recv2() {
WSADATA wsa;
memset(&wsa, 0, sizeof(wsa));
int error = WSAStartup(MAKEWORD(2, 2), &wsa);
SOCKET btSocket = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
SOCKADDR_BTH sockAddr;
memset(&sockAddr, 0, sizeof(sockAddr));
sockAddr.addressFamily = AF_BTH;
sockAddr.serviceClassId = RFCOMM_PROTOCOL_UUID;
sockAddr.port = BT_PORT_ANY;
BTH_ADDR tmpaddr = 0;
sscanf_s("7C:9E:BD:4C:BF:B2", "%02x:%02x:%02x:%02x:%02x:%02x", &aaddr[0], &aaddr[1], &aaddr[2], &aaddr[3], &aaddr[4], &aaddr[5]);
*&sockAddr.btAddr = 0;
for (i = 0; i < 6; i++) {
tmpaddr = (BTH_ADDR)(aaddr[i] & 0xff);
*&sockAddr.btAddr = ((*&sockAddr.btAddr) << 8) + tmpaddr;
}
connect(btSocket, (SOCKADDR*)&sockAddr, sizeof(sockAddr));
const int outLen = 1;
char charOut[outLen];
recv(btSocket, charOut, outLen, 0);
cout << charOut;
closesocket(btSocket);
cout << WSAGetLastError();
}
int main() {
recv2();
}
解决方案
您不应该在每次发送和读取时重新初始化 Winsock 或重新创建蓝牙套接字。初始化 Winsock 一次,最好在应用启动时。然后创建 1 个套接字并根据需要重用它。
此外,您根本不需要charIn[]
缓冲区send2()
,因为您可以传递in
给send()
:
send(btSocket, in.c_str(), (int)in.size(), 0);
无论如何,您的垃圾问题是因为您没有在发送数据之后发送空终止符,并且您没有对正在读取的缓冲区进行空终止,但是您正在显示缓冲区,就好像它是空终止的一样。您需要注意的返回值recv()
并仅显示您实际收到的字节数,例如:
const int outLen = 1;
char charOut[outLen+1];
int numBytes = recv(btSocket, charOut, outLen, 0);
if (numBytes > 0) {
charOut[numBytes] = '\0';
cout << charOut;
}
或者:
const int outLen = 1;
char charOut[outLen];
int numBytes = recv(btSocket, charOut, outLen, 0);
if (numBytes > 0) {
cout.write(charOut, numBytes);
}
推荐阅读
- angular - 在我刷新页面之前,角度路由器链接不起作用
- amazon-s3 - 通过 CDK 部署更改时需要帮助了解不一致的行为和 KMS 错误
- r - 用 x 图例中的年份替换月份
- python - 检测进程是否正在运行的最快方法
- android - 使用颤振应用程序阅读 whatsapp 通知
- python - 如何使用 python 或 perl 通过 ssh 在另一个 shell 中发送命令
- docker - kafka connect to export jmx metrics的docker compose文件中的env变量应该是什么
- vba - VBA - 趋势线方程仅在单步执行时可用,而不是运行
- macos - 在 React Native macOS 上安装 pod 时某些库的兼容性问题
- json - 如何使用具有多个页面的 API?