我尝试过使用GDB和Valgrind,但我似乎无法确定问题所在。有趣的是,程序在正常执行和GDB期间崩溃,而不是Valgrid。
为了帮助你跟上代码,这里是程序的基本要点:通过套接字和UDP与服务器通信来传输文件,并处理一些基本的数据包丢失。
我不会分享服务器的代码,因为我知道问题不存在。有一点可能会让一些人感到困惑,那就是我自己在用一个数字生成器实现丢包。现在除了让程序使用另一个recvfrom之外,它什么也没做。为了指导您完成程序的输出,客户端告诉服务器它想要什么文件,服务器告诉客户端它要发送的文件有多大,然后以块(每次10个字符)发送。
输出显示发送了什么块,接收了多少字符,以及连接的字符串是什么。
文件传输成功,从我可以告诉,它只是fopen调用,我用来写收到的文件,给我麻烦。不确定这是否与我的malloc调用有关。
源代码如下:
pastebin.com/Z79hvw6L
以下是CLI执行的输出,和Valgrind (GDB似乎没有给出任何更多的信息):
注意CLI给出malloc内存损坏错误,而Valgrind没有。
CLI: http://pastebin.com/qdTKMCD2
VALGRIND: http://pastebin.com/8inRygnU
谢谢你的帮助!
添加GDB回溯结果
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(+0x6b961)[0x19a961]
/lib/i386-linux-gnu/libc.so.6(+0x6e15d)[0x19d15d]
/lib/i386-linux-gnu/libc.so.6(__libc_malloc+0x63)[0x19ef53]
/lib/i386-linux-gnu/libc.so.6(+0x5c2b8)[0x18b2b8]
/lib/i386-linux-gnu/libc.so.6(fopen+0x2c)[0x18b38c]
/home/---/client[0x8048dc2]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xe7)[0x145e37]
/home/---/client[0x8048871]
也许这可以让某人了解错误在程序的哪个部分?
char chunk[10];
chunk[10] = ' ';
是错误的,chunk[10]是一个数组。
一般来说,要小心
char filename[25];
scanf("%s",filename);
如果你输入一个很长的文件名,你会浪费内存。使用fgets()会更好。您至少还需要检查scanf是否成功,否则filename上的strlen()无效。
第93行,buf[strlen(buf)-1]=' ';
是危险的,如果缓冲区还没有null终止,你不能使用strlen,如果buf是一个空字符串,你会垃圾内存,因为你索引buf[-1]。
编辑。你的另一个问题是strcat(fullstring,chunk);
,你没有控制在你的循环,停止追加到这个字符串,如果你碰巧收到更多的数据比它可以容纳。大小也可能相差1,因为您需要为最后一个null终止符留出空间。让它至少是char * fullstring = malloc(sizeof(char)*filesize + 1 );
,但是你的循环真的需要检查它是不是写过缓冲区的末尾。
对于向buf
添加空终止符,recv调用返回您读取的字节数,因此,如果您检查了recv的错误,请执行buf[numbytes] = 0
,但这也将被关闭一个,因为您已经为buf
分配了10个字节,并且您也尝试读取10个字节-但在C中,字符串也需要空终止符的空间。设置为11字节大。或者recv()只有9个字节。
事实上,你偏离了很多位,所以开始计算你需要多少字节,以及你是在哪里放东西进去的。请记住,在C中,数组从索引0开始,并且一个包含10的数组只能通过索引0到9进行索引。
下面(第93行)是可疑的:
buf[strlen(buf)-1]=' ';
UPDATE This (line 99,100)也是错误的:
char chunk[10];
chunk[10] = ' ';
UPDATE2:缓冲区太小
char * fullstring = malloc(sizeof(char)*filesize); // line 103
...
strcat(fullstring,chunk); // line 124
UPDATE3:UDP不可靠。数据包的传输可能会失败(数据包可能在发送者和接收者之间的任何地方被丢弃),并且数据包可能以与发送它们的顺序不同的顺序被接收。
嗯,这在现代OS:es上应该不是问题,但是您不会检查malloc()的返回值是否为NULL。在哪条线路上,在什么信号下发生了事故?