使用strcmp()从客户端读取数据不能按预期工作

时间:2014-06-25 16:04:52

标签: c strcmp strncmp

我正在进行一项练习,我需要在客户端和服务器之间建立网络并让他们“聊聊”#34;我需要检查客户端的具体响应,然后让服务器采取相应的行动。要从客户端读取数据,我使用的函数在循环中调用recv(),直到' \ n'字符,或没有更多的字节要读取。循环结束时,数组中的最后一个字符设置为' \ 0'。当函数完成后,我希望得到一个空终止的字符串,然后我可以在比较中使用它。 这是函数 -

int read_in(int socket, char *buf, int len) {
    char *s = buf;
    int slen = len;
    int c = recv(socket, s, slen, 0);
    while((c>0) && (s[c-1]!='\n')) {
        s+=c; slen-=c;
        c = recv(socket, s, slen, 0);
    }
    if (c<0) {
        return c;
    } else if (c==0) {
        buf[0] = '\0';
    } else {
        s[c-1] = '\0';
    }
    return len-slen;
}

现在,我等待连接,声明一个名为&#34的数组; buf&#34;存储我用上面的函数读取的内容,然后用strcmp()

比较2个字符串
int connect_d = accept(listener_d, (struct sockaddr *)&client_addr, &address_size);
char buf[255];
read_in(connect_d, buf, sizeof(buf));
if (strcmp("Hello\0", buf) == 0) {
    puts("Hello");
} else {
    puts("Not Hello");
}

我相信&#34; buf&#34; string包含&#34; Hello \ 0&#34;因此比较应该是成功的。但事实并非如此。我无法弄明白为什么。但是,如果我使用strncmp()比较2个字符串的前5个字节,则比较通过。但是当我比较前6个字节时,它会失败。我想知道什么存储在第6个字节位置失败了。

2 个答案:

答案 0 :(得分:1)

有一些可能性:

  1. read_in()中,如果您要阅读的最后一个字符为buf,则将NUL添加到'\n',但如果您在recv()的最后一次调用中读取了0个字节{1}},你做buf[0] = '\0';。您应该将其更改为s[0] = '\0';以保留您之前阅读的内容(说实话,如果您的情况发生了这种情况,strncmp("Hello", buf, 5)也无法正常工作,但我想指出无论如何问题)
  2. 如果客户端发送的行超过一行,您可以收到某些行。在"Hello\nWorld\n"的一次调用中与read_in()相同,您可以将buf设为"Hello\nWorld"
  3. 是Windows客户端吗?在这种情况下,您可以收到"Hello\r\n",因此您已将c[s-2]设置为'\0'(请注意,这两个字符可能会被recv()的不同调用收到)
  4. 也许客户没有发送"Hello\n",但"Hello \n"会发送类似
  5. 的内容

    只需添加printf()(例如printf( "buf[5] = %x\n", buf[5] & 0xff );)即可查看您收到了什么

    修改

    现在我们知道,服务器收到"Hallo\r\n",我建议您将其添加到read_in()的末尾(如果是c >= 0):

     int buflen = strlen( buf );
     if( buflen > 0 && buf[buflen-1] == '\r' )
          buf[buflen-1] = '\0';
    

答案 1 :(得分:-2)

服务器很可能只发送了五个字节'H','e','l','l','o'而不是零字节。 strcmp期望字符串以零字节结尾(并且C编译器将零字节添加到字符串文字中,因此“Hello \ 0”非常无意义)。

你想要检查返回的字节数是否为5,并且memcmp(“Hello”,buf,5)返回0.你需要检查单独返回的字节数,否则回复如“Hello my friend” “将被解释为”你好“。