从socket fd读取的意外值

时间:2013-06-18 18:03:07

标签: 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; 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);

并且客户端写道:

do
{
    gets(sendBuff);
    write(sockFd, &sendBuff, sizeof(sendBuff));
    sleep(1);
}while(1);

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

1 个答案:

答案 0 :(得分:3)

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

  1. 可能会以失败状态返回,或
  2. 读取的字节数可能少于请求的字节数。
  3. ALSO: 客户端使用以下行发送ENTIRE'sendBuff':

    write(sockFd, &sendBuff, sizeof(sendBuff));
    

    你可能只希望发送字符串本身(带有一些终止字符,如'\ 0'或'\ n')。使用sizeof(sendBuff)将发送在gets()输入的实际文本,'\ 0'终止符,然后在调用sendBuff之前发送gets()中已存在的任何随机字节。

    将该行更改为

    write(sockFd, &sendBuff, strlen(sendBuff) + 1);
    

    只写文本和'\ 0',而不是任何额外的垃圾。

    另外,请勿使用gets()。这是邪恶的。 (感谢Jonathan Leffler对此的提醒。)