【问题标题】:C - fwrite() not writing first chuck of data from network bufferC - fwrite() 没有从网络缓冲区写入第一批数据
【发布时间】:2021-09-21 19:49:23
【问题描述】:

我正在尝试通过编写一个基本上对我家庭网络上的专用服务器执行“cp”命令的程序来练习我的 C 编程。

通信似乎很好,但由于某种原因,通过线路发送的前 8kb 数据没有使用 fwrite 写入文件...但是 PNG 标头正在部分发送。

Client.c

uint32_t buffersize = BUFFERSIZE_M; // 8192
size_t file_index;
last_iteration = 0;
char confirmation[BUFFERSIZE_M] = {0};

            if(filelen > buffersize)
            {
                // Read full buffersize
                // subtract buffersize from filesize to determine remainder
                // if remainder is > buffersize -> repeat; else read last segment of file.
                // fileindex is used to guide the filepointer to where the buffer endpoint was/is.

                fread(buffer, 1, buffersize, file);
                file_index = buffersize;

                fseek(file, 0, file_index);
                #ifdef DEBUG
                    printf("filesize: %ld\t\tbuffersize: %d\n", filelen, buffersize);
                #endif
                // Send buffer full of file contents
                getchar(); // Only here so I can visually step through sends

                send(sock, buffer, strlen(buffer), 0);
                
                filelen = filelen - buffersize;
                file_index = file_index + buffersize;

                // Read socket for confirmation to continue
                // read(sock, confirmation, BUFFERSIZE_S);
                recv(sock, confirmation, BUFFERSIZE_S, 0);

                if(strncmp(confirmation, filename, strlen(filename)) == 0)
                    continue;
                else
                {
                    free(buffer);
                    close(sock);
                    fclose(file);
                    return -1;
                }
            }

Server.c

                while(done == FALSE)
                {
                    // if((s_read = read(s_socket, f_buffer, BUFFERSIZE_XL)) != 0)
                    if((s_read = read(s_socket, f_buffer, BUFFERSIZE_M)) != 0)
                    {
                        if(strncmp(f_buffer, "DONE", strlen("DONE")) == 0)
                        {
                            done = TRUE; 
                        }    
                        else
                        {
                            printf("strlen(buffer): %ld\ts_read: %ld\n", strlen(f_buffer), s_read);
                            fwrite(f_buffer, s_read, 1, output_file);
                            send(s_socket, filename, strlen(filename), 0);
                        }    
                    }
                    else
                    {
                        send(s_socket, filename, strlen(filename), 0); 
                    } 

                    memset(f_buffer, 0, s_read);   
                }

正确 PNG 的 Hexdump

0000000 5089 474e 0a0d 0a1a 0000 0d00 4849 5244
0000010 0000 6c05 0000 8303 0608 0000 2800 48cb
* Normal file contents until 0x2000 *
0002000 **75cc 65f8 6678** 00e9 e732 adf2 e47d 83ee

丢失 8kb 块的 Hexdump

0000000 5089 474e 0a0d 0a1a **75cc 65f8 6678** 0ae9
0000010 de20 8651 eaca 14e3 f7d4 e816 a67f f41f

然后损坏的PNG文件的其余部分丢失了,您可以从损坏的PNG中的0ae9看到它应该是00e9

谁能指出一些 C 网络缓冲资源的方向?除了人们在讨论如何创建套接字之外,我似乎在 Youtube 上找不到任何东西。

【问题讨论】:

  • 到处添加错误检查。
  • 如果你使用TCP socket,就不需要实现任何流量控制和缓冲区控制。在应用程序级别实现的唯一事情是检查各处的错误,因为 - 通过构造 - TCP 是一个可靠的协议。如果数据不能正确传输(无错误、无重复、正确顺序等),保证会出错。
  • 发送二进制数据时不要使用strlen()。它不会在缓冲区中的空字节之后发送任何内容。
  • 问题出在这里:send(sock, buffer, strlen(buffer), 0);
  • @robertstrickland 我真的建议你到处测试错误代码。调试时,例如查看send() 的返回码会立即指出@Barmar 在上面的评论中告诉你的错误。

标签: c sockets networking buffer


【解决方案1】:

来自 cmets 中的@Barmar:

问题出在这里:send(sock, buffer, strlen(buffer), 0);

这解决了问题,现在一切正常。

【讨论】:

  • '现在一切正常'....你可能会这样想:(
猜你喜欢
  • 2011-08-11
  • 1970-01-01
  • 2012-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多