实现数据链路协议。我设法通过虚拟串口发送了整个文件--这应该是困难的部分。奇怪的是,当我试图保存它时,fclose()上出现了分段故障。正在创建该文件,这意味着打开是成功的,但没有存储在其中。甚至在保存文件之前,将实现更改为将所有文件缓冲到内存中。
int app_rx(const char* outputFile){
file_data_t fileData;
if(!receive_ctrl_pckt(&fileData)){
printf("Could not receive control packet\n");
return FAILURE;
}
printf("Receiving file [%s]\nFile size: %d\n", fileData.fileName, fileData.fileSize);
unsigned char fileBuffer[fileData.fileSize];
int fileIndex = 0;
int totalBytes = 0;
int stop = 0;
size_t sqNo = 0;
int bytes;
FILE* out = fopen(outputFile, "w");
do{
activeBuffer = (activeBuffer + 1) % 2;
printf("Receiving packet %lu\n", sqNo);
bytes = llread(BUFFERS[TMP_BUFFER]);
if(bytes == DUP_ERR){
printf("Duplicate data. Discarding packet\n");
}
else if (bytes == WH_ERR){
printf("Invalid header. Discarding packet\n");
}
else if (bytes == WD_ERR){
printf("Corrupted data. Awaiting retransmission\n");
}
else{
printf("Packet %lu successfully received\n", sqNo);
int retrieveRes = retrieve_payload(sqNo);
switch(retrieveRes){
case CTRL_END: {
stop = 1;
break;
}
case FAILURE: {
printf("Unknown error\nExiting...");
exit(1);
}
case SQ_ERR:{
printf("Unsynchronized packets\nExiting");
exit(1);
}
default:{
for(int i = 0; i < retrieveRes; i++){
fileBuffer[fileIndex] = BUFFERS[activeBuffer][i];
fileIndex++;
}
sqNo = (sqNo + 1) % 255;
totalBytes += bytes;
break;
}
}
}
}while(!stop);
printf("file index: %d\n", fileIndex);
fwrite(fileBuffer, sizeof(unsigned char), fileIndex, out);
printf("here\n");
fclose(out);
if(totalBytes == fileData.fileSize){
return SUCCESS;
}
else{
return FAILURE;
}
}Stdout:
Packet 9 successfully received
Receiving packet 10
Asserting data integrity
Packet 10 successfully received
Receiving packet 11
Asserting data integrity
Packet 11 successfully received
file index: 10968
here
make: *** [Makefile:35: run_rx] Segmentation fault (core dumped)巨大的方法,我知道。只是试着在重构之前把它藏起来。为了什么也搞不清到底发生了什么。我知道这是可行的,因为我使用这个方法复制了完全相同的文件,使用的是一个简单的com.file.c测试驱动程序,它模仿cp命令。
有什么想法吗?我觉得特别奇怪的是,它创建了输出文件,但是没有在上面写任何东西。
编辑:通过在写入文件之前打开文件来使其正常运行。还是不太明白发生了什么
发布于 2022-11-18 14:09:13
数组fileBuffer存在潜在的缓冲区溢出风险,除了保证retrieveRes小于或等于fileData.fileSize之外,如果存在缓冲区溢出,则指针输出可能被覆盖,并在调用fclose时导致段错误。缓冲区溢出可以通过在do/while循环之前打印out的值并调用fclose来验证。
https://stackoverflow.com/questions/74312871
复制相似问题