C 从套接字fd读取的意外值

C 从套接字fd读取的意外值,c,sockets,tcp,file-descriptor,C,Sockets,Tcp,File Descriptor,在实现TCP服务器/客户端聊天时,我想验证新客户端的用户名是否不存在。 服务器的代码部分是: do { err=0; if(write(socketFd[(int)idx], nickMsg, strlen(nickMsg))<0) perror("write"); memset(buff, 0, sizeof(buff)); read(socketFd[(int)idx], buff, sizeof(buff)); for(i=0;

在实现TCP服务器/客户端聊天时,我想验证新客户端的用户名是否不存在。 服务器的代码部分是:

do
{
    err=0;
    if(write(socketFd[(int)idx], nickMsg, strlen(nickMsg))<0)
        perror("write");
    memset(buff, 0, sizeof(buff));
    read(socketFd[(int)idx], buff, sizeof(buff));
    for(i=0; i<supportedUsrsNum; i++)
    {
        if(*names[i]!=0)
        {
            if(strncmp(buff, names[i], strlen(buff))==0)
            {
                err=-1;
                write(socketFd[(int)idx], usrExstMsg, strlen(usrExstMsg));
                break;
            }
        }
    }
    if(!err)
        break;
}
while(err==-1);

当第二个客户端尝试现有名称时,服务器会检测到该名称并进行第二次迭代,在该迭代中,其read()的ASCII值为3,但客户端没有进一步的输入。我遗漏了什么以及如何从客户端重新读取新值?

可能是
read()
实际读取的不是ASCII 3,而是零字节。可能发生了错误情况。始终检查调用
read()
的返回值

  • 它可能返回故障状态,或
  • 它读取的字节数可能少于请求的字节数
  • 此外: 客户端正在使用此行发送整个“sendBuff”:

    write(sockFd, &sendBuff, sizeof(sendBuff));
    
    您可能只想发送字符串本身(带有一些终止字符,如“\0”或“\n”)。使用
    sizeof(sendBuff)
    将发送在
    gets()
    处输入的实际文本、“\0”终止符,然后发送调用
    gets()
    之前已存在于
    sendBuff
    中的任何随机字节

    把那句话改成

    write(sockFd, &sendBuff, strlen(sendBuff) + 1);
    
    只写入文本和“\0”,而不写入其后的任何额外垃圾


    另外,不要使用
    gets()
    。这是邪恶的。(感谢Jonathan Leffler提醒。)

    可能是
    read()
    实际上并没有读取ASCII 3,而是读取零字节。可能发生了错误情况。始终检查调用
    read()
    的返回值

  • 它可能返回故障状态,或
  • 它读取的字节数可能少于请求的字节数
  • 此外: 客户端正在使用此行发送整个“sendBuff”:

    write(sockFd, &sendBuff, sizeof(sendBuff));
    
    您可能只想发送字符串本身(带有一些终止字符,如“\0”或“\n”)。使用
    sizeof(sendBuff)
    将发送在
    gets()
    处输入的实际文本、“\0”终止符,然后发送调用
    gets()
    之前已存在于
    sendBuff
    中的任何随机字节

    把那句话改成

    write(sockFd, &sendBuff, strlen(sendBuff) + 1);
    
    只写入文本和“\0”,而不写入其后的任何额外垃圾


    另外,不要使用
    gets()
    。这是邪恶的。(感谢Jonathan Leffler提醒。)

    不要使用
    get()
    ;使用
    fgets()
    。你不能用
    gets()
    @JonathanLeffler看起来像强大的
    gets()
    防止缓冲区溢出,这是由于我写的长度错误造成的。谢谢很高兴你解决了。我的
    gets()
    注释是看到函数被使用时的下意识反应。缺少很多错误检查,包括(至关重要的)检查
    read()
    的返回值。您的客户端
    write()
    应该发送
    strlen(sendBuff)
    而不是
    sizeof(sendBuff)
    字节,可能还有一个
    +1
    来发送终端空值。如果不通过线路发送null,读取代码将不会接收到它,并且接收到的字符串可能不会以null结尾(除非您确保它是以null结尾的)。Colin D Bennett已经在公认的答案中写下了这些问题,所以一切都很好。不要使用
    get()
    ;使用
    fgets()
    。你不能用
    gets()
    @JonathanLeffler看起来像强大的
    gets()
    防止缓冲区溢出,这是由于我写的长度错误造成的。谢谢很高兴你解决了。我的
    gets()
    注释是看到函数被使用时的下意识反应。缺少很多错误检查,包括(至关重要的)检查
    read()
    的返回值。您的客户端
    write()
    应该发送
    strlen(sendBuff)
    而不是
    sizeof(sendBuff)
    字节,可能还有一个
    +1
    来发送终端空值。如果不通过线路发送null,读取代码将不会接收到它,并且接收到的字符串可能不会以null结尾(除非您确保它是以null结尾的)。Colin D Bennett已经在公认的答案中写下了这些问题,所以一切都很好。我用你的
    strlen(sendBuff)+1改为
    fgets
    。工作起来很有魅力。谢谢我用你的
    strlen(sendBuff)+1更改为
    fgets
    。工作起来很有魅力。谢谢