首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >recv仅获取包的前4个字节

recv仅获取包的前4个字节
EN

Stack Overflow用户
提问于 2013-01-04 05:01:10
回答 3查看 2.4K关注 0票数 3

我正在用C++编写一个客户端应用程序,以便通过UDP广播接收二进制数据,但是,无论缓冲区大小如何,我都无法接收前4个字节以外的任何数据。我检查了Wireshark中的数据包,可以看到我的机器正在接收大约1200字节的数据。当我将其与我的客户端接收的数据进行比较时,我可以看到我正在接收数据包,但是剩余的数据丢失了。下面是我的代码:

代码语言:javascript
复制
#define BUFFERSIZE 4096
int main()
{
    struct addrinfo hints, *servinfo, *p;
    int sockfd, i, nbyt;

    int *buf = (int*) malloc(BUFFERSIZE);

    memset(&hints, 0, sizeof hints);
    hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_DGRAM;
    hints.ai_flags = AI_PASSIVE;

    getaddrinfo(NULL, "9011", &hints, &servinfo);

    sockfd = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol);
    bind(sockfd, servinfo->ai_addr, servinfo->ai_addrlen);

    FILE *file;
    file = fopen("file.txt", "w+");

    for (i=0;i<=45;i++)
    {
        nbyt = recv(sockfd, buf, BUFFERSIZE, 0);            
        fprintf(file, "%s %d; %s %x\n", "Bytes received:", nbyt, "Message:", *buf);
    }

    fclose(file);
    close(sockfd);
    free(buf);

    printf("%s\n", "Execution ended.");

    return 0;
}

下面是我接收到的一些数据的示例:

代码语言:javascript
复制
Bytes received: 1131; Message: 5b0
Bytes received: 1131; Message: 5b3
Bytes received: 1131; Message: 5b6
Bytes received: 1092; Message: 4e0

我尝试使用MSG_DONTWAIT标志将套接字设置为非阻塞,因为这解决了类似Python应用程序的问题,但这只会返回错误:

代码语言:javascript
复制
Bytes received: -1; Message: 0

我对C++和套接字比较陌生,所以可能有一些我没有看到的东西。希望有人能帮我找出问题所在?如有必要,我可以提供更多信息。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-01-04 05:05:49

你能很好地收到它。您的调试代码并不像您所认为的那样工作。

printfx说明符以十六进制打印无符号整型参数。您的平台上的整数可能是32位的。所以你只打印了前4个字节。

如果您想以十六进制打印整个缓冲区,则需要自己编写循环(当然,也可以使用库)。

例如,我警告你,我的C语言有点生疏了(到目前为止,这不是实现这一点的最佳方式)……此外,这还假设您的缓冲区始终是sizeof(int)的倍数,否则会丢失一些数据:

代码语言:javascript
复制
nbyt = recv(sockfd, buf, BUFFERSIZE, 0);            
fprintf(file, "%s %d; %s\n", "Bytes received:", nbyt, "Message:");
for (offset = 0; offset < nbyt/sizeof(int); ++offset) {
    fprintf(file, "%x ", buf[offset]);
}
fprintf(file, "\n");
票数 4
EN

Stack Overflow用户

发布于 2013-01-04 05:13:27

代码中的*buf表示接收到的数据数组中的第一个整数,因此只打印接收到的UDP有效载荷的前四个字节。

票数 1
EN

Stack Overflow用户

发布于 2013-01-04 05:55:27

尽管存在前面提到的格式错误,但如果您收到一个'\0‘字符,则带有%s的格式化打印将在那里剪切字符串,而不管实际收到的字符数是多少。

为了调试纯文本,我使用了以下代码:

代码语言:javascript
复制
char escaped_char(char c)
{
    char escapable[12] =    {'\a','\b','\f','\n','\r','\t','\v','\\','\'','\"','\?','\0'};
    char escaped[12]   =    { 'a', 'b', 'f', 'n', 'r', 't', 'v','\\','\'','\"', '?', '0'};

    const char* escapable_end = escapable + 12;
    const char* ec;

    for(ec = escapable;ec != escapable_end;++ec)
    {
        if(c == *ec) return escaped[ec-escapable];
    }
    return 0;
}

/**
 * @param   buf     input buffer to escape
 * @param   len     length of contents in buf
 * @param   outlen  pointer to an integer, which receives the length of the returned string
 * @return          A newly allocated, C style escaped string, NULL on error
 * @warning         A returned string must be freed with free()
 */
char* aescape(const char* buf,size_t len,size_t* outlen)
{
    const char* buf_end = buf + len;
    const char* c;
    char ec;
    char* result;

    assert(buf && outlen);

    (*outlen) = len;

    for(c = buf;c != buf_end;++c)
    {
        if(escaped_char(*c))
        {
            ++*outlen;
        }
    }
    result = malloc((*outlen)+1);
    assert(result != NULL);
    if(result)
    {
        if((*outlen) > len)
        {
            char* out = result;
            for(c = buf;c != buf_end;++c)
            {
                ec = escaped_char(*c);
                if(ec)
                {
                    *out++ = '\\';
                    *out++ = ec;
                }
                else
                {
                    *out++ = *c;
                }
            }
        }
        else
        {
            memcpy(result,buf,len);
        }
        result[(*outlen)] = '\0';
    }
    else
    {
        (*outlen) = 0;
    }
    return result;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14147173

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档