解析内存映射文件C

3
我正在构建一个功能性的DNS服务器,需要一些帮助来完成它。目前我打开服务器并使用dig命令发送请求。问题是如何正确地回答它们。在此之前,我已经在内存中映射了一个包含域名和IP地址的文件(使用mmap),因此如果我收到任何有关本地地址的请求,我可以通过解析从链接列表中获取请求并提取所需信息的线程中的mmaped文件来回答它。我只是似乎找不到一个正确的方法。
下面是我的mmap代码:
void mmap_localdns(){
    int ldns;
    char *data;
    struct stat size;
    ldns=open("localdns.txt", O_RDONLY);
    stat("localdns.txt", &size);
    data = mmap((caddr_t)0, size.st_size, PROT_READ, MAP_SHARED, ldns, 0);
    close(ldns);
    printf("%s", data);

    char *pch;
    pch = strtok(&data, " ");

    while(pch != NULL){
        printf("%s\n", pch);
        pch = strtok(NULL, " ");
    }
    //munmap(data, size.st_size);
}

我尝试使用strtok()但它一直给我一个分段错误。可能这不是最好的解决方案 :/

我说的文件遵循以下规则:

mywebserver.so.local 192.168.1.20
fileserver.so.local 192.168.1.10
ww5.so.local 192.168.1.5

感谢您的选择 :)

3
您真的想在每个请求中都解析文件吗?这听起来会有很多开销。我认为您应该只解析一次文件,将数据放入哈希表中,然后使用该数据结构。另外,您的问题是什么? - 5gon12eder
4
strtok 修改了被搜索的字符串,但该文件已使用 PROT_READ 映射,这很可能是段错误的原因。对于这样的应用程序,使用 mmap 没有太多优势,更好的选择是使用 fgets。另外,正如先前的评论中已经提到的,不断解析并不高效。只需解析文件一次(或每次更改时),然后每次使用该结果即可。 - kaylum
1
好的,很公平。那么您应该以可写模式打开文件并进行映射,以便它是可写的。此外,您可能希望使用MAP_PRIVATE而不是MAP_SHARED,因为您不太可能希望strtok处理更改底层文件。 - kaylum
1
关于单次解析 - 只需创建一个数据结构来存储解析结果,进行一次解析,然后从那时起引用数据结构而不是每次重新解析文件。 - kaylum
1
strtok会修改给定的char指针地址,如果您不小心恢复char指针地址以供其他用途,则可能会导致段错误。例如,将另一个char设置为等于"data"地址,然后在处理"data"变量上使用strtok之后,将"data"指针地址设置回新char指针的地址。 - Mike -- No longer here
显示剩余4条评论
1个回答

4
你正在使用带有O_RDONLY标志的文件打开方式,并使用PROT_READ进行内存映射,这都是好的。 然而,请注意strtok()函数会修改其参数。换句话说,你正在违反承诺,从而写入了mmap返回给你的内存位置。 解决方案是使用任何真正只读的内存例程。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接