【问题标题】:How to properly close a socket opened with fdopen?如何正确关闭使用 fdopen 打开的套接字?
【发布时间】:2013-09-22 21:19:57
【问题描述】:

我有一个套接字sock

int sock = socket(...);
connect(sock, ...);
 // or sock = accept(sock_listen, 0, 0);

并且我用fdopen打开了两次,这样就可以使用stdio中的缓冲读写器,比如fwritefreadfgetsfprintf

FILE *f_recv = fdopen(sock, "wb");
FILE *f_send = fdopen(sock, "rb");

// some IO here.

close(sock);
fclose(f_recv);
fclose(f_send);

但正如我们所知,如果我 fclose 一个文件,随后将调用 close,而 fclose 将失败。

如果我只使用close,结构FILE的内存就会泄露。

如何正确关闭?


更新:

fdopen"r+"一起使用一次可以使读写共享同一个锁,但我除了发送和接收单独工作。

【问题讨论】:

  • 您没有“打开它两次”。您只是将 STDIO 流包裹在它周围。由于您给出的原因,您需要关闭它们。

标签: c++ c sockets posix glibc


【解决方案1】:

使用 dup() 获取复制文件描述符以传递给 fdopen()。当您调用 fclose() 时,它将被关闭,但底层套接字将保持打开状态,并且可以使用 close() 关闭:

FILE *f_recv = fdopen(dup(sock), "wb");
FILE *f_send = fdopen(dup(sock), "rb");

// some IO here.

fclose(f_recv);
fclose(f_send);
close(sock);

编辑:您当然可以将其与仅使用单个 FILE 对象进行读取和写入相结合。

【讨论】:

    【解决方案2】:

    由于您给出的原因,我认为两次调用fdopen() 是错误的。

    只需使用fdopen() 打开一次,传递模式字符串"r+b" 以使其读/写和二进制。

    【讨论】:

    • 等一下……这引入了一个新问题。 stdio 填充物在每次调用时锁定“文件”,或者在使用 flockfile 手动锁定时。但实际上,读写应该是单独锁定的。
    猜你喜欢
    • 2012-01-17
    • 1970-01-01
    • 2016-02-14
    • 1970-01-01
    • 2012-02-10
    • 2017-12-24
    • 1970-01-01
    • 2018-07-27
    • 2020-03-20
    相关资源
    最近更新 更多