Можно ли преобразовать дескрипторы сокетов в указатели файлов?

Я получил дескриптор TCP-сокета следующим образом:

int desc = accept(socket_descriptor, &client_address, &len)

Теперь из этого дескриптора desc я хочу получить указатель на файл. Можно ли здесь использовать fdopen()?

Причина, по которой я хочу получить указатель файла, заключается в том, что я вношу изменения в существующий код, который записывает данные в локальный файл. Теперь я хочу расширить его функциональность, чтобы в качестве альтернативы он мог писать на TCP-клиент. Я не хочу переписывать все функции и думал о том, чтобы как-то использовать существующую инфраструктуру. Существующие функции используют указатель файла для записи в файл. Мне было интересно, можно ли заставить ту же функцию записывать в поток TCP без внесения каких-либо изменений.


person AnkurVj    schedule 15.10.2011    source источник


Ответы (1)


Да, fdopen() — это именно то, что вы необходимость. Вот что говорит справочная страница об этом:

Функция fdopen() связывает поток с существующим файловым дескриптором fd. Режим потока (одно из значений "r", "r+", "w", "w+", "a", "a+") должен быть совместим с режимом дескриптора файла. Индикатор позиции файла нового потока устанавливается равным тому, который принадлежит fd, а индикаторы ошибки и конца файла сбрасываются. Режимы "w" или "w+" не вызывают усечения файла. Дескриптор файла не дублируется и будет закрыт при закрытии потока, созданного функцией fdopen(). Результат применения fdopen() к объекту разделяемой памяти не определен.

Но используйте его с осторожностью при применении к дескрипторам сокетов. Функции ввода-вывода высокого уровня используют буферизацию и могут отправлять данные по-разному (т. е. сбрасывать всякий раз, когда в потоке встречается \n, вставлять \r) и т. д.

person Community    schedule 15.10.2011
comment
Большинство файлов не буферизуются строками, только stdout. Я не уверен, есть ли способ настроить файл для буферизации строк, но я считаю, что большинство из них будут буферизованы блоками, что должно быть немного более удобным для сокетов. - person Chris Lutz; 16.10.2011
comment
@ChrisLutz: функция setlinebuf. Я думаю, что stdout буферизируется только строка, если она подключена к терминалу, но я не уверен. - person Dietrich Epp; 16.10.2011
comment
@DietrichEpp - Спасибо. И я думаю, что вы правы насчет stdout. - person Chris Lutz; 16.10.2011
comment
Меня беспокоит строка, в которой говорится, что режим потока должен быть совместим с режимом файлового дескриптора. Должен ли я использовать w в моем сценарии? - person AnkurVj; 16.10.2011
comment
@AnkurVj: Почему бы тебе не попробовать? Я бы рекомендовал начинать с w+ или bw+, если текстовые и двоичные файлы обрабатываются по-разному (например, в Windows). - person ; 16.10.2011
comment
Я пробовал + и r+. r+ работает только в Mac OS X/iOS, тогда как a+ также работает в Linux 3.2.0. - person ZhangChn; 05.02.2013
comment
@ZhangChn: r+ У меня работает в Linux. - person ; 09.02.2013