缓冲套接字末端的垃圾

Garbage at the end of buffer socket

当我通过串行终端发送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 个套接字并根据需要重复使用它。

此外,您根本不需要 send2() 中的 charIn[] 缓冲区,因为您可以将 in 传递给 send():

send(btSocket, in.c_str(), (int)in.size(), 0);

无论如何,您的垃圾问题是因为您没有在发送的数据之后发送一个空终止符,并且您没有以空终止符终止您正在读入的缓冲区,但是您显示的缓冲区就好像它是空终止。需要注意recv()的return值,只显示实际收到的字节数,eg:

const int outLen = 1;
char charOut[outLen+1];
int numBytes = recv(btSocket, charOut, outLen, 0);
if (numBytes > 0) {
    charOut[numBytes] = '[=11=]';
    cout << charOut;
}

或者:

const int outLen = 1;
char charOut[outLen];
int numBytes = recv(btSocket, charOut, outLen, 0);
if (numBytes > 0) {
    cout.write(charOut, numBytes);
}