首页 > 解决方案 > 为什么 Winsock recvfrom() 缓冲区返回“E”?

问题描述

我正在尝试使用 Winsock 接收数据包,并且能够从 recvfrom() 命令获得返回,但是当我尝试打印缓冲区中保存的数据时,我只得到 E。

这是我使用 recvfrom 命令的地方:

    i = 0;
    while (i < 25) {
        data_len = recvfrom(raw_socket, rcvbuf, sizeof(rcvbuf), 0, (SOCKADDR*)&sender_addr, &sender_addr_size);

        std::cout << "Iteration: " << (i);
        printf("\nReceived packet from %s:%d\n", inet_ntoa(sender_addr.sin_addr), ntohs(sender_addr.sin_port));
        printf("Length of bytes received: %d\n", data_len);
        printf("Data: %s\n", rcvbuf);
        std::cout << "\n\n";
        i = i + 1;
    }  

运行代码时的示例返回:
迭代:21
隐藏 IP接收到的数据包:0
接收到的字节长度:1385
数据:E

它不是缓冲区大小的错误,并且从几个小时的在线搜索中我找不到任何描述我的问题的东西。如果有人知道这里发生了什么,我将非常感谢一个解释,甚至更好,一个修复。

其他可能有用的代码:

    char rcvbuf[10000];    
...
    // create a raw socket
    raw_socket = socket(AF_INET, SOCK_RAW, 0);
    if (raw_socket == INVALID_SOCKET) {
        printf("Error at socket(): %ld\n", WSAGetLastError());
        WSACleanup();
        return 1;
    }
...
    // Bind the IPv4 address to the socket
    if0.sin_addr.S_un.S_addr = inet_addr(local_ip);
    if0.sin_family = AF_INET;
    if0.sin_port = htons(14996);;
    if (bind(raw_socket, (SOCKADDR*)&if0, sizeof(if0)) == SOCKET_ERROR) {
        printf("bind() failed with error code %d\n", WSAGetLastError());
        return -1;
    }
    else printf("bind() is OK!\n");

感谢所有帮助过的人:) 我为在缓冲区中打印二进制数据所做的更改(不考虑字节顺序):

    // receive all packages in a while loop
    std::cout << "Connected on IPv4 Address: " << local_ip << "\n";
    i = 0;
    while (i < 2) {
        data_len = recvfrom(raw_socket, rcvbuf, sizeof(rcvbuf), 0, (SOCKADDR*)&sender_addr, &sender_addr_size);

        std::cout << (i);
        printf("\nReceived packet from %s:%d\n", inet_ntoa(sender_addr.sin_addr), ntohs(sender_addr.sin_port));
        printf("Length of bytes received: %d\n", data_len);
        printf("Data: ");
        //std::cout.write(rcvbuf, data_len);

        std::string s = rcvbuf;
        for (int i2 = 0; i2 < data_len;) {
            std::cout << std::bitset<8>(s[i2]) << " ";
            i2 = i2 + 1;
        }

        std::cout << "\n--------------------------\n";
        memset(rcvbuf, 0, 10000);
        i = i + 1;
    }

标签: c++visual-studiowinapinetworkingwinsock

解决方案


您没有使用正确的输出函数来查看数据。您正在使用假定字符串数据以空值结尾的函数:

printf("Data: %s\n", rcvbuf);

这将打印内容,rcvbuf直到到达空终止符。这一点很可能比data_len字符少。

要正确打印数据,您可以使用以下std::cout.write()功能:

std::cout.write(rcvbuf, data_len);


推荐阅读