2010-06-19 93 views
1

我正在写简单的服务器/客户端在c,其中服务器临时存储来自客户端的消息,并在客户端请求时检索它。从插座读取缓冲区

问题是当客户端收到来自服务器的消息时,缓冲区有点奇怪。 所有我所做的是多读,从服务器接收并打印在屏幕上,但不知何故,缓冲液overwrited比缓冲区的最大尺寸更

在客户端

while((byteRead = recv(ssock, buffer, MAXBUF, 0)) > 0) 
{ 
    if(byteRead <= 0) 
     break; 
    printf("%s", buffer); 
} 

其中MAXBUF是256.保持包含一些garbages,所以我在缓冲 检查字符串大小和令人惊讶的

printf("%d READ vs %d buffer strlen \n", byteRead, strlen(buffer)) 

告诉我,byteRead是256,但缓冲区的字符串长度为262

任何想法?

P.s在服务器端,它正确读取文件并将其发送到套接字上。

回答

13

recv不会在字符串的末尾放置空终止符(而printf%s假定有一个)。

您必须使用byteRead来确定字符串的长度。如果要使用printf之类的函数,请添加空终止符,但请确保即使在最大尺寸读取时,缓冲区也有空间。

1

是的。

strlen()查找最近的NULL终止符,如在常规C字符串中一样。

recv()与null结束符无关,不会添加一个。所以,strlen调用是错误的,甚至可能会因未经授权的读取而导致程序崩溃。

+0

确定我得到了这一点。但在服务器端,当客户端通过套接字向服务器发送消息时,它会正确接收并且我没有添加空指针。即使我以为我发送给客户端之前我添加了空指针,它仍然显示垃圾的东西; – REALFREE 2010-06-19 08:18:34

+0

@REALFREE:当我们说空终止符时,我们正在谈论“nul”*字符*,而不是空*指针*。此外,在你的服务器的情况下,它可能会出现*工作,因为祝你好运,但你做的事情不合适。 – Artelius 2010-06-19 08:50:11

4

这里的问题是buffer不是由recv()以NULL结尾。实际上,recv只将原始套接字数据放入缓冲区。如果它接收到256字节的数据,那么随后出现的任何内容都可能为空字符(例如它在服务器上),或者可能是其他内容(如它在客户端上)。这是程序执行的一个神器,而不是你如何编程它。

的最简单和最快的方式来解决这个问题:

  1. 分配buffer与大小MAXBUF + 1。 +1将用于额外的NULL字符。
  2. 紧接在printf之前,在buffer[bytesRead]处添加空字符。

所以全告诉:

buffer = malloc((MAXBUF + 1) * sizeof(char));   // NEW 

while((byteRead = recv(ssock, buffer, MAXBUF, 0)) > 0) 
{ 
    if(byteRead <= 0) 
     break; 
    else { 
     buffer[bytesRead] = '\0';      // NEW 
     printf("%s", buffer); 
    } 
}