简体   繁体   English

从套接字读取缓冲区

[英]reading buffer from socket

I'm writing simple server/client in c, where server temporary stores message from client and retrieve it when client request it. 我正在用c编写简单的服务器/客户端,其中服务器临时存储来自客户端的消息,并在客户端请求时检索它。

The problem is when client receives message from server, the buffer acts kinda weird. 问题是当客户端从服务器接收消息时,缓冲区有点奇怪。 All i did is read as much as receive from server and print it on the screen, but somehow buffer was overwrited more than maximum size of buffer 我所做的全部与从服务器接收到的一样多,并且将其打印在屏幕上,但是不知何故,缓冲区被覆盖的程度超过了缓冲区的最大大小

in client 在客户中

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

where MAXBUF is 256. It keep contains some garbages so i examined the string size in buffer and surprisingly 其中MAXBUF是256。它包含一些垃圾,因此我检查了缓冲区中的字符串大小,并且令人惊讶地

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

show me that byteRead is 256 but string length of buffer is 262. 告诉我byteRead是256,但是缓冲区的字符串长度是262。

Any idea?? 任何想法??

Ps on server side, it reads file correctly and send it onto socket. 服务器端的ps,它正确读取文件并将其发送到套接字。

recv does not place a null terminator at the end of the string (whilst printf %s assumes there is one). recv不会在字符串的末尾放置一个空终止符(而printf %s假定存在一个终止符)。

You must use byteRead to determine the length of the string. 您必须使用byteRead来确定字符串的长度。 Add a null terminator if you want to use a function like printf , but ensure your buffer has the space for it even on a maximum-size read. 如果要使用类似printf ,请添加一个空终止符,但即使在最大大小的读取时,也要确保缓冲区具有printf的空间。

The problem here is that buffer is not NULL-terminated by recv() . 这里的问题是buffer不是由recv()终止的。 In fact, recv only puts the raw socket data into the buffer. 实际上, recv仅将原始套接字数据放入缓冲区。 If it recieves 256 bytes of data, whatever comes after that might be null characters (eg as it is on your server) or it might be something else (as it is on your client). 如果它接收256个字节的数据,则其后的内容可能是空字符(例如,在您的服务器上),也可能是其他字符(在您的客户端上)。 It's an artifact of program execution, not of how you programmed it. 这是程序执行的产物,而不是您如何编程的产物。

The easiest and fastest way to fix this: 解决此问题的最简单,最快的方法:

  1. Allocate buffer with size MAXBUF + 1 . 分配大小为MAXBUF + 1 buffer The +1 will be for an extra NULL character. +1将代表一个额外的NULL字符。
  2. Immediately before the printf , add a null character at buffer[bytesRead] . printf之前,立即在buffer[bytesRead]处添加一个空字符。

So all-told: 所以说:

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

Yes. 是。

strlen() looks for the nearest NULL terminator, as in a conventional C string. 像传统的C字符串一样,strlen()查找最接近的NULL终止符。

recv() has nothing to do with null terminator and would not add one. recv()与空终止符无关,也不会加一个。 So, the strlen call is wrong and may even crash your program by unauthorized read. 因此,strlen调用是错误的,甚至可能因未经授权的读取而使程序崩溃。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM