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

C:read()中的套接字返回>;读取0字节,但缓冲区为零,c,sockets,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 o

我正在尝试从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=read(newsockfd,buffer,sizeof(int));
int bytes_to_read=atoi(缓冲区);
fprintf(stdout,“这里是要查找的数据的大小:%d”,字节到读取);
/*阅读信息*/
fprintf(stdout,“读取第一条消息。\n”);
int字节读取=0;
int chunk=bytes\u to\u read>255?255:读取的字节数;
做{
b0(缓冲器,256);
n=读取(newsockfd、缓冲区、块);
字节_read+=n;
fprintf(stdout,“n的值是%d,这是第一次读取后的新缓冲区:%s,新缓冲区长度是:%d\n”,n,buffer,strlen(buffer));
strcat(纯文本、缓冲区);
大小+=256;
明文=realloc(明文,大小);
}while(字节读取<字节读取);
我得到的输出显示n=36(如预期),但buffer是0,buffer的长度是1

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

编辑: 根据我得到的反馈,我彻底地重写了这篇文章。注意,我知道客户机将发送一个包含数据中字节数的数据包作为一个单元32,然后它将发送数据

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; }`
char*readText(int newsockfd){
char*text=malloc(256);
字符缓冲区[256];
int n;
int size=256;
/*找出数据中有多少字节*/
uint32字节到字节读取;
n=读取(newsockfd,&bytes_to_read,sizeof(uint32_t));
字节到字节读取=NTOLL(字节到字节读取);
/*从客户端读取数据*/
int bytes_read=0;
int bytes_left=字节_to_read;
/*我们一次最多可以读取255字节,因为这是缓冲区的大小。
*缓冲区可能会更大,但我们仍然需要检查数据大小并继续调用
*读取()直到获得所有数据。
*如果要读取的数据小于缓冲区,则我们只需一次性读取。如果数据较大,
*然后,我们以255字节大小的块读取它,直到我们读取了所有数据*/
int chunk=(字节到字节读取>255)?255:字节到字节读取;
做{
b0(缓冲器,256);
n=读取(newsockfd、缓冲区、块);
/*将我们目前读取的数据复制到文本缓冲区中
我们用已经读入的数据进行抵消,这样就不会覆盖已经存在的数据
阵列中*/
memcpy(文本+字节\读取,缓冲区,n);
字节_read+=n;
字节_left-=n;
/*如果剩下的字节少于255个,只需读取该数量。这可以防止read()拉入太多数据并扰乱下一个read()调用*/
chunk=(剩余字节>255)?255:剩余字节;
大小+=n;
/*将文本变量的大小增加到我们刚刚读入的大小。这为
下一个数据块。下一个数据块可能大到255字节*/
text=realloc(文本,大小);
}while(字节读取<字节读取);
text[bytes_read]='\0';//null终止字符串,以便对其使用字符串函数。
如果(n<0)错误(“从套接字读取错误”);
返回文本;}`
  • 不能保证你收到了完整长度的信息

  • 您正在读取它的
    sizeof int
    字节,它表示二进制数据,但随后调用
    atoi()
    ,它表示十进制字符串形式的以null结尾的ASCII数据。是哪一个

  • 如果您得到的返回值为36,则表示接收到的字节数,如果缓冲区包含
    {0,1}
    ,则表示也接收到了该字节数

  • 仅在任意字节数组上使用
    strlen()
    strcat()
    是无效的。这些函数用于以null结尾的字符串。TCP并没有说您接收的每个缓冲区都是以null结尾的字符串,也没有说您接收的内容甚至是可打印的


  • 您所做的只是无效。

    buffer
    是指向缓冲区的指针(或者缓冲区本身,如果它声明为数组),并且它的长度是您分配的字节数。这不会改变。1)从套接字读取时,应使用“recv()”而不是“read()”2)read/recv不会终止读入数据。因此,代码必须具体做到这一点。3) 在第一次调用strcat()之前,“明文[]”的第一个字节必须是“\0”4)strlen(缓冲区)可以是任何内容,因为读取字符串尚未终止,5)使用realloc()时,在将返回值分配给目标指针之前始终检查(!=NULL),继续:6)第一次调用read()需要4个ascii字符(sizeof(int))。这可能正确,也可能不正确。如果只传输3个字符,函数将永远挂起,7)在发布的代码中还有一些其他问题与这一行有关:“int chunk=bytes\u to\u read>255?255:bytes_to_read;'由于C操作员的主持,此线路可能会失败。建议:'int chunk=(字节到读取>255)?255:bytes_to_read;'OP:True,关于接收了多少字节,您唯一知道的信息是
    read()
    的返回值。我不想问太宽泛的问题,但是有关于这类事情的教程吗?我不知道有任何教程涵盖了所有细节。所说的是来自经验的“硬”手。