2013-06-18 14 views
0

实现TCP服务器/客户端聊天,我想验证新客户端的用户名已不存在。 服务器的代码部分是:从套接字读取的意外值fd

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); 

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

+2

不要使用'gets()';使用'fgets()'。你不能用'gets()'来防止缓冲区溢出。 –

+0

@JonathanLeffler看起来像强大的'gets()'造成了我的错误长度写作的麻烦。谢谢!! – winuall

+1

很高兴你解决了它。我的'gets()'注释对于看到使用的函数是一个膝盖反应。有很多错误检查丢失,包括(关键),检查'read()'的返回值。你的客户端'write()'应该发送'strlen(sendBuff)'而不是'sizeof(sendBuff)'字节,可能用'+ 1'来发送一个终端null。如果您不通过线路发送null,则读取代码将不会收到它,并且收到的字符串可能不以null结尾(除非您确定它是否为空)。 Colin D Bennett在接受的答案中写下了这些问题,所以一切都很好。 –

回答

3

可能是read()实际上并不是读取ASCII 3,而是读取零字节。也许发生了错误情况。经常检查,因为

  1. ,可能与故障条件归还或者
  2. 它可以读取比请求的字节数较少调用read()的返回值。

ALSO: 客户与该行发送整个“sendBuff”:

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

,你可能只想发送字符串本身(与像“\ 0”或部分终止字符'\ n')。使用sizeof(sendBuff)将发送在gets(),'\ 0'终止符处输入的实际文本,然后在调用gets()之前发送sendBuff中已存在的任何随机字节。

把上面一行类似

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

写的文字,只有“\ 0”,而不是后,任何额外的垃圾。

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

+0

我用'strlen(sendBuff)+ 1'改为'fgets'。奇迹般有效。谢谢!! – winuall