我正在进行一项练习,我需要在客户端和服务器之间建立网络并让他们“聊聊”#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个字节位置失败了。
答案 0 :(得分:1)
有一些可能性:
read_in()
中,如果您要阅读的最后一个字符为buf
,则将NUL添加到'\n'
,但如果您在recv()
的最后一次调用中读取了0个字节{1}},你做buf[0] = '\0';
。您应该将其更改为s[0] = '\0';
以保留您之前阅读的内容(说实话,如果您的情况发生了这种情况,strncmp("Hello", buf, 5)
也无法正常工作,但我想指出无论如何问题)"Hello\nWorld\n"
的一次调用中与read_in()
相同,您可以将buf
设为"Hello\nWorld"
"Hello\r\n"
,因此您已将c[s-2]
设置为'\0'
(请注意,这两个字符可能会被recv()
的不同调用收到)"Hello\n"
,但"Hello \n"
会发送类似只需添加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” “将被解释为”你好“。