C中的套接字:read()返回>读取0个字节,但缓冲区为零

时间:2015-06-04 01:30:58

标签: c sockets

我试图从C中的套接字读取数据。将会有两条消息。

我正在尝试将消息的大小发送到套接字,以便read()命令知道消息何时结束并且可以在该点停止读取。否则,它会将两条消息都读入一个blob。问题是read命令将缓冲区设置为0,即使它读取> 0个字节。

以下是代码:

n = read(newsockfd, buffer, sizeof(int)); 
     int bytes_to_read = atoi(buffer); 
     fprintf(stdout, "Here is the size of the data to look for: %d", bytes_to_read);
     /*read message*/
     fprintf(stdout, "Reading first message.\n");
     int bytesread = 0;
     int chunk = bytes_to_read > 255 ? 255 : bytes_to_read;  
     do {
        bzero(buffer,256);
        n = read(newsockfd,buffer,chunk);
        bytes_read += n; 
        fprintf(stdout, "The value of n is %d and here is the new buffer after the first read: %s and new buffer length is : %d\n", n, buffer, strlen(buffer));
        strcat(plaintext, buffer); 
        size += 256;
        plaintext = realloc(plaintext, size); 
     } while (bytes_read < bytes_to_read);

我得到的输出显示n = 36(如预期的那样),但缓冲区为0,缓冲区长度为1。

为什么read()命令将缓冲区设置为0?有没有更简单的方法告诉read()在哪里停止阅读?

编辑: 根据我得到的反馈,我彻底重写了这一点。请注意,我知道客户端将发送一个包含数据中字节数的数据包作为unit32_t,然后它将发送数据。

char * readText(int newsockfd) {
char * text = malloc(256); 
char buffer[256];
int n; 
int size = 256;
/*find out how many bytes are in the data*/
 uint32_t bytes_to_read; 
 n = read(newsockfd, &bytes_to_read, sizeof(uint32_t)); 
 bytes_to_read = ntohl(bytes_to_read); 

 /*read data from client*/
 int bytes_read = 0;
 int bytes_left = bytes_to_read; 
 /*the maximum we can read at one time is 255 bytes since that is the size of the buffer. 
 * the buffer could have been larger but we'd still have to check the data size and keep calling
 * read() until we get all of the data. 
 * If the data to read is smaller than the buffer, then we just read it in one go. If the data is larger, 
 * then we read it in 255 byte-sized chunks until we have read all of it*/ 
 int chunk = (bytes_to_read > 255) ? 255 : bytes_to_read;
 do {
    bzero(buffer,256);
    n = read(newsockfd,buffer,chunk);
    /*copy over the data we have read so far into the text buffer
    We offset by the amount we have already read in so we do not overwrite the data already 
    in the array*/
    memcpy(text + bytes_read, buffer, n);
    bytes_read += n; 
    bytes_left -= n; 
    /*if we have less than 255 bytes left, just read that amount. This prevents read() from pulling in too much data and messing up the next read() call*/ 
chunk = (bytes_left > 255) ? 255 : bytes_left;
    size += n;
    /*grow the text variable by as much as we just read in. This makes room for 
    the next chunk of data. The next chunk could be as large as 255 bytes*/ 
    text = realloc(text, size); 
 } while (bytes_read < bytes_to_read); 
 text[bytes_read] = '\0'; //null terminate our string so we can use string functions on it. 
 if (n < 0) error("ERROR reading from socket");
return text; }`

1 个答案:

答案 0 :(得分:2)

  1. 无法保证您收到了整篇邮件。

  2. 您正在读取sizeof int个字节,这表示二进制数据,但您正在调用atoi(),这会以十进制字符串的形式建议以空值终止的ASCII数据。这是什么?

  3. 如果您获得的返回值为36,即收到的字节数,以及缓冲区是否包含{0, 1},那也是收到的。

  4. 在任意字节数组上使用strlen()strcat()无效。这些函数用于以null结尾的字符串。 TCP没有任何内容表明您收到的每个缓冲区都是一个以空字符结尾的字符串,并且没有任何内容可以显示您收到的信息。

  5. 你所做的事情根本无效。