首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Recv()跳过字节

Recv()跳过字节
EN

Stack Overflow用户
提问于 2017-04-16 00:54:00
回答 1查看 278关注 0票数 0

我在一个基本的TCP连接上使用recv。这是我正在读取的[]字节:0 4 9 0

下面是recv调用,最后是上下文中的代码

代码语言:javascript
复制
recv(fd_serv, &len, sizeof (len), MSG_NOSIGNAL);
len = ntohs(len);
recv(fd_serv, &tool_id, sizeof (tool_id), MSG_NOSIGNAL);
recv(fd_serv, rdbuf, len, MSG_NOSIGNAL);

在gdb中调试时,我可以看到

代码语言:javascript
复制
len = 4
tool_id = 9
rdbuf = [ 0 4 9 0 ] / [ 0 4 \t 0 ]

那件事怎么可能?看起来,recv的开头两个字节表示len,下一个字节用于tool_id (就像长度/大小),而rdbuf则接受所有字节。我希望它是一致的。我认为这可能是一个部分字节读取功能,但显然我错了。

如果我移除

代码语言:javascript
复制
recv(fd_serv, &tool_id, sizeof (tool_id), MSG_NOSIGNAL);

从代码中选中gdb中的rdbuf,执行后的前两个字节更改。

代码语言:javascript
复制
recv(fd_serv, rdbuf, len, MSG_NOSIGNAL);

它变成

代码语言:javascript
复制
[ 9 0 9 0 ] / [ \t 0 \t 0 ]

当我再次取消评论时,rdbuf又是正常的。起初,我以为没有读取的剩余字节被复制过来了。我将rdbuf3设置为5,并认为它可能会取代0,但它没有。到目前为止,我还不知道这里发生了什么,为什么这里不一致。

我使用7.12.1,gcc 6.3.1构建:

代码语言:javascript
复制
gcc -g -DDEBUG *.c -o client.dbg -lcrypto

上下文

代码语言:javascript
复制
while(TRUE) { 
    if (fd_serv != -1 && FD_ISSET(fd_serv, &fdsetrd)) {
        int n;
        uint16_t len;
        uint8_t tool_id;
        char rdbuf[1024];

        errno = 0;
        n = recv(fd_serv, &len, sizeof (len), MSG_NOSIGNAL | MSG_PEEK);
        if (n == -1) {
            if (errno == EWOULDBLOCK || errno == EAGAIN || errno == EINTR)
                continue;
            else
                n = 0; 
        }

        if (n == 0) {
            close_connection();
            continue;
        }

        if (len == 0) {
            recv(fd_serv, &len, sizeof (len), MSG_NOSIGNAL);
            continue;
        }
        len = ntohs(len);
        if (len > sizeof (rdbuf)) {
            close(fd_serv);
            fd_serv = -1;
        }

        errno = 0;
        n = recv(fd_serv, rdbuf, len, MSG_NOSIGNAL | MSG_PEEK);
        if (n == -1) {
            if (errno == EWOULDBLOCK || errno == EAGAIN || errno == EINTR)
                continue;
            else
                n = 0;
        }

        if (n == 0) {
            close_connection();
            continue;
        }

        recv(fd_serv, &len, sizeof (len), MSG_NOSIGNAL);
        len = ntohs(len);
        recv(fd_serv, &tool_id, sizeof (tool_id), MSG_NOSIGNAL);
        recv(fd_serv, rdbuf, len, MSG_NOSIGNAL);

        printf("%d\n", tool_id);
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-04-16 01:31:36

在这种情况下,检查recv的返回值会有所帮助(作为对Michael评论的响应)。我得出的结论是,上一次recv调用不是读取所有字节,而是读取剩余字节。在这种情况下是1或2。然后将字节放在开头,而不覆盖旧值。我想这个组合让我困惑了。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43432666

复制
相关文章

相似问题

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