我正在编写一个小的客户端/服务器C程序。客户端中的一个函数将用于询问服务器目录中所有常规文件的名称。服务器将通过TCP以char数组的形式返回文件名。我的程序有很多选择,可以单独运行任何次数,并且可以轻松切换。当我尝试运行该函数以获取文件名时,出现段错误,并且不知道为什么。我已经在下面粘贴了客户端和服务器代码。
服务器:
void dir_details(int socket) {
//Set up appropriate variables
char StringArray[1024];
struct dirent *de;
struct stat st = {0};
//If the upload directory doesn't exist, create it
if (stat("upload", &st) == -1) {
mkdir("upload", 0777);
}
//Opening the upload directory to be read
DIR *dr = opendir("upload");
if (dr == NULL) {
printf("Could not open directory.");
}
//Add each file name to a char array
while ((de = readdir(dr)) != NULL) {
strcat(StringArray, de->d_name);
strcat(StringArray, "\n");
}
closedir(dr);
size_t n = sizeof(StringArray);
//Send the char array back to the client
writen(socket, (unsigned char *) &n, sizeof(size_t));
writen(socket, (unsigned char *) StringArray, n);
strcpy(StringArray, "");
free(de);
}
客户:
void dir_details(int socket) {
//Set up char array to be received form the server
char dirdetails[5000];
size_t k;
//Receive char array from the server
readn(socket, (unsigned char *) &k, sizeof(size_t));
readn(socket, (unsigned char *) &dirdetails, k);
//Print the array to the client
printf("%s\n", dirdetails);
}
答案 0 :(得分:2)
仔细阅读 readdir(3)。实际上,struct dirent
的最后一个成员d_name
可能会像flexible array member那样运行,即使它可能没有完全记录下来。
您的StringArray
可能有一个buffer overflow(并且您检查得不够仔细)。您忘记将其归零(至少使用memset(StringArray, 0, sizeof (StringArray));
...)
当然,您误解了malloc。它可能会失败,并且您始终需要使用它的结果。进一步了解C dynamic memory allocation。
阅读How to debug small programs。编译所有警告和调试信息,如果使用GCC,则使用gcc -Wall -Wextra -g
。
花几天时间阅读有关基本C编程的更多信息。阅读一些C tutorial。查看一些C reference网站。如有疑问,请阅读有关C编程的好教程后,再检查C11标准n1570。研究小型free software程序的源代码以获取灵感。
提高了基本的C编程技能后,请阅读有关Linux编程的知识,例如ALP。
销毁您的废话程序(它有很多错误,因此不值得改进或尝试挽救)。 一旦您提高了C编程水平,就可以从头开始重新编写程序。使用一个好的版本控制系统(我建议使用git),并做一些非常iterative and incremental development的操作(写一两行,将它们与所有警告一起编译,将其改进为没有警告,使用GDB debugger对其进行测试,然后将其提交给您的版本控制,然后重复所有操作)。仔细阅读正在使用的每个函数的文档(例如{man
页,例如read(2),syscalls(2),errno(3),printf(3),等等...)
NB。在触摸键盘之前,您可能应该花至少一个星期的时间阅读。我实际上建议阅读SICP(这是一本很好的编程入门,它不使用C,但是却讲授了非常重要和相关的概念)