Socket编程——服务端内容写入客户端(write())

Socket Programming - Server content written to Client (write())

我正在编写一个文件导航器,它将客户端连接到服务器并让用户列出服务器当前目录(服务器位置)中的所有文件。

假设该目录包含以下文件:

test.txt
Makefile
server.c

现在,我希望用户(在客户端)能够在服务器端获得所有 files/foldes 的列表。

我已经编写了一段显示所有文件的工作代码,但仅在服务器端。它看起来如下:

void print_content(int socket_num) {
    struct dirent *entry;   //Entry
    DIR *dir_stream;    //Directory stream
    dir_stream = opendir("./"); //Open current directory
    if(dir_stream != NULL) {
        while((entry = readdir(dir_stream))) {
            printf("%s\n", entry->d_name); //Gets name
            write(socket_num, entry->d_name, 1024); //WRITE?
        }
        (void) closedir(dir_stream);
    }
    else {
        error("Problems with directory");
    }
}

如前所述,这在服务器端正确打印出来。

但是,有没有一种方法可以轻松地将这些字符串发送到客户端,而不是使用 write() 函数?

换句话说,有没有比 write() 更类似于 printf() 的函数,它写入客户端?

In other words, is there a function more similar to printf() than write(), that writes to a client?

是的,有 fprintf(),如果您首先 fdopen() 一个流( 一个 FILE *),您可以将其用于此目的围绕您连接的套接字的文件描述符。最好在所有 fprintf() 之后 fflush() 确保最后的比特没有延迟地发送,并且绝对在丢弃流之前发送。

但是,您可能不想这样做。 [f]printf()用于格式化数据;将其发送到选定的目的地是次要的考虑因素,尽管很重要。除非您描述的客户端非常瘦,否则您可能希望客户端而不是服务器执行格式化。在这种情况下,您需要做的是序列化[需要的部分] a struct dirent,并将那些发送给客户端,让它随意使用。如果您只是通过套接字传递格式化数据,那么客户端除了吸收所有传入数据并按原样在 UI 中吐出外,无能为力。唯一和永远。这或多或少就是我所说的 "exceedingly thin".

此外,如果您确实创建了一个流,请注意,当您关闭它时,您也将关闭底层套接字。另一方面,如果你丢弃它而不关闭它,那么这将构成资源泄漏。