А>Можно ли под Windows с помощью функции fprintf писать в socket. И, соответственно, считывать fscanf?
А ты сам как думаешь?
Да здравствует мыло душистое и веревка пушистая.
Re[2]: socket и fprintf
От:
Аноним
Дата:
29.04.04 08:00
Оценка:
Здравствуйте, alexora, Вы писали:
A>Здравствуйте, Аноним, Вы писали:
А>>Можно ли под Windows с помощью функции fprintf писать в socket. И, соответственно, считывать fscanf?
A>как мне память не изменят в fpintf передается указатель на тип FILE
Это все понятно, но есть такая вещь как
FILE *_fdopen( int handle, const char *mode );
если ей передать сокет, то возвращает 0. Но если перед этим сделать
long h=_get_osfhandle(sock)
то возвращается вполне "приличное" значение h. И fdopen с этим h возвращает тоже вполне "приличное" значение. И даже работает fprintf, пока пишет в буфер. Но если делаешь fflush — результат -1. Тот же рез-т при попытке записи _write( int handle, const void *buffer, unsigned int count ). Где-то на Linux-овом форуме видел как человек связывал сокет с stdin, stdout, правда у него возникали проблемы с буферизацией, советовали ее отключить. Но, я так понял, что в Linux это возможно.
Если в Win так нельзя, то за каким .... смущать людей тем, что _get_osfhandle и _fdopen с сокетом работают, вроде бы правильно.
В принципе, готов смириться с sprintf(...);send(...), но, как кто-то писал: "Уж больно красоты хочется".
Re[3]: socket и fprintf
От:
Аноним
Дата:
29.04.04 08:21
Оценка:
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, alexora, Вы писали:
A>>Здравствуйте, Аноним, Вы писали:
А>>>Можно ли под Windows с помощью функции fprintf писать в socket. И, соответственно, считывать fscanf?
A>>как мне память не изменят в fpintf передается указатель на тип FILE
А>Это все понятно, но есть такая вещь как
А>FILE *_fdopen( int handle, const char *mode );
А>если ей передать сокет, то возвращает 0. Но если перед этим сделать
А>long h=_get_osfhandle(sock)
А>то возвращается вполне "приличное" значение h. И fdopen с этим h возвращает тоже вполне "приличное" значение. И даже работает fprintf, пока пишет в буфер. Но если делаешь fflush — результат -1. Тот же рез-т при попытке записи _write( int handle, const void *buffer, unsigned int count ). Где-то на Linux-овом форуме видел как человек связывал сокет с stdin, stdout, правда у него возникали проблемы с буферизацией, советовали ее отключить. Но, я так понял, что в Linux это возможно. А>Если в Win так нельзя, то за каким .... смущать людей тем, что _get_osfhandle и _fdopen с сокетом работают, вроде бы правильно. А>В принципе, готов смириться с sprintf(...);send(...), но, как кто-то писал: "Уж больно красоты хочется".
Дико извиняюсь, не на того пожаловался: не _get_osfhandle, а _open_osfhandle. А в остальном, все так как написано. У _open_osfhandle есть еще флаги, возможно, загвоздка в них.
Re[3]: socket и fprintf
От:
Аноним
Дата:
29.04.04 09:23
Оценка:
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, alexora, Вы писали:
A>>Здравствуйте, Аноним, Вы писали:
А>>>Можно ли под Windows с помощью функции fprintf писать в socket. И, соответственно, считывать fscanf?
A>>как мне память не изменят в fpintf передается указатель на тип FILE
А>Это все понятно, но есть такая вещь как
А>FILE *_fdopen( int handle, const char *mode );
А>если ей передать сокет, то возвращает 0. Но если перед этим сделать
А>long h=_get_osfhandle(sock)
А>то возвращается вполне "приличное" значение h. И fdopen с этим h возвращает тоже вполне "приличное" значение. И даже работает fprintf, пока пишет в буфер. Но если делаешь fflush — результат -1. Тот же рез-т при попытке записи _write( int handle, const void *buffer, unsigned int count ). Где-то на Linux-овом форуме видел как человек связывал сокет с stdin, stdout, правда у него возникали проблемы с буферизацией, советовали ее отключить. Но, я так понял, что в Linux это возможно. А>Если в Win так нельзя, то за каким .... смущать людей тем, что _get_osfhandle и _fdopen с сокетом работают, вроде бы правильно. А>В принципе, готов смириться с sprintf(...);send(...), но, как кто-то писал: "Уж больно красоты хочется".
Забей.
1) Наверняка stdlib начнёт глючить, если низлежащие операции записи/чтения будут возвращать ошибки. Точнее, не ошибки, а, скажем низлежащая операция, запишет 4K из 40 и скажет — остальное потом. FILE перейдёт в состояние ошибки, и что дальше — закрывать сокет и открывать его заново?
2) HANDLE, который возвращает CreateFile(), file descriptor, которым пользуется fdopen() & Co и HANDLE сокета, это, IMHO, 3 разные вещи. В частности, HANDLE сокета вроде бы не является объектом ядра в Windows, в отличие от HANDLE файла.
Пиши в буфер, а для передачи используй свою функцию, которая корректно обрабатывает "частичную" передачу данных низлежащим уровнем.
Здравствуйте, Аноним, Вы писали:
А>>FILE *_fdopen( int handle, const char *mode );
А>>если ей передать сокет, то возвращает 0. Но если перед этим сделать
А>>long h=_get_osfhandle(sock)
А>>то возвращается вполне "приличное" значение h. И fdopen с этим h возвращает тоже вполне "приличное" значение. И даже работает fprintf, пока пишет в буфер. Но если делаешь fflush — результат -1. Тот же рез-т при попытке записи _write( int handle, const void *buffer, unsigned int count ). Где-то на Linux-овом форуме видел как человек связывал сокет с stdin, stdout, правда у него возникали проблемы с буферизацией, советовали ее отключить. Но, я так понял, что в Linux это возможно. А>>Если в Win так нельзя, то за каким .... смущать людей тем, что _get_osfhandle и _fdopen с сокетом работают, вроде бы правильно. А>>В принципе, готов смириться с sprintf(...);send(...), но, как кто-то писал: "Уж больно красоты хочется". А>Дико извиняюсь, не на того пожаловался: не _get_osfhandle, а _open_osfhandle. А в остальном, все так как написано. У _open_osfhandle есть еще флаги, возможно, загвоздка в них.
Нет, вряд ли. Поиск в google по этой проблеме дает интересную возможную зацепку. Дело в том что по-умолчанию при вызове socket создается с "overlapped attribute" (не путать с blocking/nonblocking). Я сомневаюсь что функции _read/_write из MSC run-time library рассчитаны на такой режим работы (на вызовы ReadFile/WriteFile со структурой OVERLAPPED). Кстати, можете это проверить в исходниках. Или просто попробуйте вызывать не socket, а WSASocket без WSA_FLAG_OVERLAPPED (тот же эффект может дать вызов setsockopt(SO_OPENTYPE) перед вызовом socket, но это не рекомендуется).
Здравствуйте, Michael Chelnokov, Вы писали:
MC>Дело в том что по-умолчанию при вызове socket создается с "overlapped attribute" (не путать с blocking/nonblocking). Я сомневаюсь что функции _read/_write из MSC run-time library рассчитаны на такой режим работы (на вызовы ReadFile/WriteFile со структурой OVERLAPPED). Кстати, можете это проверить в исходниках.
Да, так и есть. В исходниках _write все вызовы WriteFile идут с NULL вместо OVERLAPPED*. Потому-то fflush может давать ошибку (она вызывает _write, _write вызывает WriteFile(...NULL), WriteFile возвращает FALSE и устанавливает ошибку ERROR_IO_PENDING или нечто подобное, на "ошибку" все успешно забивают).
Re[5]: socket и fprintf
От:
Аноним
Дата:
29.04.04 15:49
Оценка:
Здравствуйте, Michael Chelnokov
Большое спасибо за разъяснения.
Здравствуйте, Аноним, Вы писали:
А>2) HANDLE, который возвращает CreateFile(), file descriptor, которым пользуется fdopen() & Co и HANDLE сокета, это, IMHO, 3 разные вещи. В частности, HANDLE сокета вроде бы не является объектом ядра в Windows, в отличие от HANDLE файла.
Здрасьте! Дестрипторы сокетов не только объекты ядра, в них можно писать и читать из них функциями для файлов.