【问题标题】:C on linux: using fclose() on Filepointers made from Socket descriptorslinux上的C:在由套接字描述符制成的文件指针上使用fclose()
【发布时间】:2017-12-07 12:08:43
【问题描述】:

我必须为学校编写一个简单的命令行客户端/服务器,我们的老师告诉我们,在套接字上使用 fdopen 是一种简单的方法。给出了一个协议,该协议定义了仅由 EOF 标记的简单请求和响应(因此不在请求本身内,而是 FIN 标志必须这样做)。

现在我的问题是,为了在客户端获得响应,我必须关闭写作方向。 为此,我使用 fclose() 省略我正在做的细节(跳过所有错误处理和不相关的东西)几乎是:

sdr = socket(..); 
sdw=dup(sdr); 
writepointer = fdopen(sdw,"w");
readpointer = fdopen(sdr,"r");
send_message(writepointer); 
fclose (writepointer);

现在我希望 flcose()(成功返回 0 btw)发送 EOF、fflush()、关闭指针并关闭底层套接字描述符,从而导致 fin 标志从客户端发送到服务器。

现在,当我单步执行程序并同时查看 tcpdump 时,当我调用 fclose() 但没有 FIN 标志时,我看到请求正在发送(并由服务器确认)。 这当然会导致服务器看不到请求已完成,并且我的客户端在稍后尝试读取响应时变得非常无聊。

我没有发现很多人在这里使用文件指针进行 tcp 传输,所以搜索这个并没有产生很多结果。

以前有人遇到过这个问题吗?

【问题讨论】:

    标签: c linux sockets fclose


    【解决方案1】:

    您有两种方法可以导致 TCP 套接字关闭,但您都没有这样做。其中之一是致电shutdown。你没有那样做。另一种是关闭最后一个引用连接的描述符。你没有这样做。

    做这两件事中的一件。

    您期望这会触发关闭是不合理的。您仍然有一个对连接打开的套接字,该套接字可用于读取和写入。所以如果触发了 TCP 协议关闭,那将是相当令人惊讶的。

    【讨论】:

    • 现在就是这样:fclose() 应该在为您创建文件指针的描述符上执行 close()。相信讲师告诉我们的内容,我什至在另一个函数中建立连接,仅填充文件指针的缓冲区,而不以任何方式显式返回套接字。来自 fclose 手册页:The fclose() function flushes the stream pointed to by stream (writing any buffered output data using fflush(3)) and closes the underlying file descriptor.
    • @gotjazz84 :在这种情况下,and closes the underlying file descriptor 应该读作:“删除对文件描述符的引用”,另一个 fopen()d 文件仍然有对它的引用。
    • @joop 这就是我使用 dup 的原因。
    • 文件descriptor是对打开文件描述的一种引用。如果它是最后一个引用,则关闭前者只会关闭后者
    • 来自 dupx() 手册页:After a successful return from one of these system calls, the old and new file descriptors may be used interchangeably. They refer to the same open file description“文件描述”:=“系统文件表”中的一项
    猜你喜欢
    • 1970-01-01
    • 2012-11-12
    • 1970-01-01
    • 1970-01-01
    • 2012-04-13
    • 1970-01-01
    • 1970-01-01
    • 2014-04-17
    • 2020-05-01
    相关资源
    最近更新 更多