我尝试过使用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结果
======= 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]
也许这可以让某人了解错误所在的程序的哪个部分?
答案 0 :(得分:3)
char chunk[10];
chunk[10] = '\0';
错了,chunk [10]是一个超过数组的。
一般来说,小心这样做
char filename[25];
scanf("%s",filename);
如果输入长文件名,则会丢失内存。使用fgets()会更好。您至少还想检查scanf是否成功,否则文件名中的以下strlen()无效。
第93行,buf[strlen(buf)-1]='\0';
是危险的,如果缓冲区尚未终止,则不能使用strlen,如果buf为空字符串,则在使用strf [-1]进行索引时会丢弃内存。
编辑。
你的另一个问题是strcat(fullstring,chunk);
,如果你碰巧收到的数据多于它可以容纳的数据,那么你的循环就无法控制停止附加到这个字符串。大小也可能是一个,因为你需要最后一个nul终结器的空间。至少要char * fullstring = malloc(sizeof(char)*filesize + 1 );
但是你的循环真的需要检查它是不是写在那个缓冲区的末尾。
至于向buf
添加一个nul终止符,recv调用返回你读取的字节数,所以如果你已经检查了recv是否有错误,请执行buf[numbytes] = 0
,但这将关闭一个也是,因为你为buf
分配了10个字节,你也尝试读取10个字节 - 但在C中,字符串也需要空间来容纳nul终结符。使buf 11字节大。或者recv()只有9个字节。
事实上,你离开了很多地方,所以开始计算你需要多少字节,然后把东西放进去。请记住,在C中,数组以索引0开头,而数组10只能由索引0到9索引。
答案 1 :(得分:2)
这(第93行)是可疑的:
buf[strlen(buf)-1]='\0';
更新此(第99,100行)也是错误的:
char chunk[10];
chunk[10] = '\0';
UPDATE2:缓冲区太小
char * fullstring = malloc(sizeof(char)*filesize); // line 103
...
strcat(fullstring,chunk); // line 124
UPDATE3: UDP是不可靠的。数据包的传输可能会失败(数据包可能会丢弃在发送方和接收方之间的任何位置),并且可能会以与发送数据包不同的顺序接收数据包。
答案 2 :(得分:1)
嗯,它应该不是现代操作系统的问题:但是你不检查malloc()返回的值是否为NULL。它崩溃的路线和信号是什么?