2013-09-18 2 views
1

У меня есть гнездо sock:Как правильно закрыть сокет, открытый с помощью fdopen?

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

И я открыл ее fdopen в два раза, так что я могу использовать буферизованный читателя и писателя в stdio, такие как fwrite, fread, fgets и fprintf.

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

// some IO here. 

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

Но, как мы знаем, если I fclose файлом, close будет называться впоследствии, и fclose потерпит неудачу.

И если я использую только close, просочится память структуры FILE.

Как его закрыть?


UPDATE:

Используйте fdopen один раз "r+" делает чтение и запись долю таким же замок, но кроме передачи и приема на работу в индивидуальном порядке.

+0

Вы не открывали его дважды. Вы просто обмотали потоки STDIO вокруг него. Вам нужно закрыть их обоих по той причине, что вы дали. – EJP

ответ

1

Я думаю, что вызов по причинам, которые вы даете, является ошибкой fdopen().

Просто откройте его один раз fdopen(), передав строку режима "r+b", чтобы сделать чтение/запись и двоичным.

+0

Протестировано и работает. – RnMss

+0

Подождите минуту ... Это создает новую проблему. Материалы 'stdio' блокируют« ФАЙЛ »для каждого вызова или вручную блокируются с помощью' flockfile'. Но на самом деле чтение и письмо должны быть заблокированы индивидуально. – RnMss

0

Используйте dup() для получения дубликата дескриптора файла для перехода к fdopen(). При вызове fclose(), которые будут закрыты, но основная розетка будет оставаться открытым и может быть закрыто с близкими():

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); 

Edit: Конечно, Вы можете объединить это только с помощью одного объекта FILE для обоих чтение и письмо.

Смежные вопросы