c - C : read() returns > 0 bytes read, 中的套接字但缓冲区为零

标签 c sockets

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

我正在尝试将消息的大小发送到套接字,以便 read() 命令知道消息何时结束并可以在该点停止读取。否则,它将把两条消息读入一个 blob。问题是读取命令将缓冲区设置为 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. 不能保证您收到了完整长度的消息。

  2. 您正在读取 sizeof int 字节,这表明是二进制数据,但您随后调用了 atoi(),这表明是 null 终止的十进制字符串形式的 ASCII 数据。是哪个?

  3. 如果您得到的返回值是 36,则表示收到了多少字节,如果缓冲区包含 {0, 1},则表示收到的字节数也是如此。

  4. 仅对任意字节数组使用 strlen()strcat() 是无效的。这些函数用于以 null 结尾的字符串。 TCP 没有任何内容表明您收到的每个缓冲区都将是一个以 null 结尾的字符串,也没有任何内容表明您收到的内容甚至是可打印的。

您所做的根本无效。

关于c - C : read() returns > 0 bytes read, 中的套接字但缓冲区为零,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30633514/

相关文章:

c - 替换纯 C 中的链接器部分

c# - 如何从软件中捕获准确的 USB-HID 设备交互并在我自己的代码中重新实现它

perl - 如何通过套接字共享 Perl 数据结构?

javascript - 在我的简单 Node Js 服务器中解析请求

c++ - 在 C++ 中通过套接字发送图像

c - 当 ZMQ_FD option_val 的本地地址通过时,zmq_getsockopt 在 Windows x64 上返回 EINVAL

c - 标准输入传递流有何不同?

改变C中字符串数组中字符的值

c - 从 Linux 内核向 LOOPBACK 发送小的 UDP 数据包

C++ 在 SOCKET accept() 方法中失败