【发布时间】: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