Сегодня выходной, так что напишу коротко про мелочи, до которых, как правило, руки не доходят.

TCP FS



Есть ещё одна вещь, которой нет в современном Юниксе и которую я хочу иметь в unix box фантома. Она проста как мычание, и почему её никто не сделал — непостижимо:

#cat /tcp/host/port > local_file


Правда, я хочу использовать иной синтаксис имени файла, URL style — tcp://host:port, но это уже детали. Естественно, наравне с TCP просится UDP, и там вообще проблем нет.

Заголовок спойлера
Вообще unix-подсистема Фантома «ест» как традиционные Юниксовые имена, /usr/include/stdio.h, так и URL-и, tcp://ya.ru:80.


Для TCP есть очевидная проблема — нужен ли нам listen или connect, но её можно решить через указание в имени «файла» определённого суффикса.

Сказать на эту тему настолько больше нечего, что перейдём без остановки к следующей.

TRFS — тривиальная дистанционная файловая система.



В одной из тестовых сред Фантом работал на машине без диска и хотелось организовать дистанционный пейджинг по сети. Для этого я сделал минимальную сетевую ФС.

Ссылки:



Протокол напоминает дубовостью tftp, но допускает асинхронность — запрос не обязан синхронно ждать ответа, вместо этого клиент отправляет запросы без ожидания и стыда, может получать ответы вразнобой и перезапрашивает неполученное по таймауту.

Обмен идёт секторами. Фактически, сам Фантом использует протокол именно как remote disk.

Обращение к файлу идёт по идентификатору сессии и идентификатору файла. Это позволяет при необходимости опустить разыменование и работать с файлами по фиксированным номерам — опять же, в этой реализации так и сделано, Фантом всегда просит файл номер ноль, сервер сам знает, где его искать. Но есть и запрос «получить номер по имени».

Идентификатор сессии используется как маркер того факта, что сервер был перезапущен и забыл номера файлов. В такой ситуации идентификатор сессии покажет несовпадение и клиент получит ошибку, которую надо обработать перезапросив ещё раз номер файла для данного имени. Впрочем, эту часть протокола я не стал писать, так как мне самому она пока не нужна.

Протокол легковесный в плане реализации настолько, что даже сервер можно затолкать в слабый микроконтроллер. А уж клиента и подавно.

Протокол работает поверх UDP. Пользуйтесь на здоровье, коли потребуется. При всей простоте в силу асинхронности и out of order resend-а протокол довольно эффективен. Только если нужно упорядоченное исполнение запросов — это нужно обеспечивать снаружи. Сам TRFS счастливо отработает в порядке прихода ответов по сети.

Комментарии (87)


  1. qw1
    30.04.2016 17:38
    +3

    Идея не нова. Сокет как файловый дескриптор можно использовать в linux в стандартных функциях read/write и в Windows, в ReadFile, WriteFile.
    Другое дело, открыть сокет через обращение к open/CreateFile нельзя, но тут нарушается консистентность с файловой системой:
    1) имя tcp://host/port даётся какому объекту, виртуальному? повторное чтение вернёт другие данные? т.е. это не URI, как http://… где можно говорить о наличии адреса у определённого постоянного ресурса
    2) что насчёт stat, ls? `ls /tcp` вернёт все доступные хосты, а stat — время рождения хоста / открытия сокета на удалённой стороне?


    1. dzavalishin
      01.05.2016 00:15
      +1

      http://ya.ru?text=hello возвращает всегда одни и те же данные? побойтесь бога. :)
      что насчёт stat /dev/tty?
      ls вернёт пустоту. облом. Хотя, конечно, можно пойти до конца: /tcp/ru/ya

      реакция существующих ФС Юникса на стандартные вызовы умеренно консистента и умеренно полна. ничего нового. да хоть бы и новое. стат вернул -1 — бог мой, все умерли.


  1. Lsh
    30.04.2016 17:58
    +5

    Plan9 и протокол 9P? Есть (был? не знаю, как там дела) еще занятный PlanB.


    1. loz
      30.04.2016 23:23
      -3

      Да, Дмитрий, стыдно уж, занимаясь операционными системами не знать про 9P. И его наличие в ядре линукса.


      1. dzavalishin
        01.05.2016 00:16

        Я знаю, но он сложнее, а тащить код из Линукса — проще застрелиться. Да и лицензия…


        1. dottedmag
          01.05.2016 10:34
          +2

          MIT-овая реализация есть в Inferno и plan9port


          1. dzavalishin
            01.05.2016 13:13

            спасибо


        1. wigneddoom
          04.05.2016 20:51

          Не особо он сложный, в своё время реализовывал под МК. Реализаций море: http://9p.cat-v.org/implementations


    1. dzavalishin
      05.05.2016 10:56

      Почитал ещё раз спеку 9P. Навскидку не увидел в описании протокола обработки ситуации, когда сервер упал и рестартовал. File id недостаточно — после рестарта идентичный id может выделиться новому файлу, и клиент, который всё ещё его помнит, может обратиться не туда. Это можно закрыть через явное использование TCP, но это уже требование более высокого уровня (TRFS базируется на UDP) и нагружает протокол дополнительным слоем преобразования данных (эффективность).


  1. MooNDeaR
    30.04.2016 18:10
    +2

    Я не понял ничего :) Неплохо бы в статье было привести пару use case, где это использовать и как. Почему бы не привести описание протокола в статье? Читать на гитхабе, да еще и на вражеском, без особого форматирования как-то не очень хочется.


  1. alien007
    30.04.2016 19:25

    Обмен идёт секторами

    А какой размер сектора?
    Фактически, сам Фантом использует протокол именно как remote disk.

    А можно пояснить?
    В моем понимании remote disk — это блоковое устройство, общение с которым традиционно осуществляется по протоколу SCSI (который может инкапсулироваться хоть в IP-пакеты, хоть в FibreChannel, хоть в придуманный вами UDP/TCP протокол). Такое блоковое устройство ничего не знает о файлах, путях, атрибутах. А здесь речь идет все-таки об удаленной файловой системе.


    1. dzavalishin
      01.05.2016 00:21

      Да. Но фантом просто привязывает фиксированный файл в этой ФС к своему дисковому интерфейсу. При этом запросы преобразуются 1:1.

      Блоксайз 512, как минимальный из известных мне, при этом можно запрашивать пачку секторов одним трансфёром. Запрос имеет scatter-gather структуру, ответ имеет право быть нарезан на кусочки (в меру ограничений размера UDP пакета).


  1. farcaller
    30.04.2016 19:47
    +9

    $ exec 3<>/dev/tcp/google.com/80
    $ echo -en "GET / HTTP/1.0\n\n" >&3
    $ cat <&3
    HTTP/1.0 302 Found
    Location: http://www.google.ie/?gws_rd=cr&ei=YuEkV7GAIYmRgAbP4ZboBA
    Cache-Control: private
    Content-Type: text/html; charset=UTF-8
    P3P: CP="This is not a P3P policy! See https://www.google.com/support/accounts/answer/151657?hl=en for more info."
    Date: Sat, 30 Apr 2016 16:46:26 GMT
    Server: gws
    Content-Length: 258
    X-XSS-Protection: 1; mode=block
    X-Frame-Options: SAMEORIGIN
    Set-Cookie: NID=79=HvOpf6lsXXis3fovmnHG_mRShtGaFIGCv_lS8lBdqcbSwAnZ5jPm9fPlznmxTiJMnsIvm7H1xbqrDhLBtizqTLfXMj5YuYj5FX8x3OdFeyDRy1coRn92y66-ANaIrU7u; expires=Sun, 30-Oct-2016 16:46:26 GMT; path=/; domain=.google.com; HttpOnly
    
    <HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
    <TITLE>302 Moved</TITLE></HEAD><BODY>
    <H1>302 Moved</H1>
    The document has moved
    <A HREF="http://www.google.ie/?gws_rd=cr&ei=YuEkV7GAIYmRgAbP4ZboBA">here</A>.
    </BODY></HTML>
    


    Оно?


    1. Zolushok
      30.04.2016 21:59

      Ну и для тех, кого пугает bash с его перенаправлениями, есть socat со всеми этими tcp: и tcp-listen:


    1. reji
      30.04.2016 22:17
      +1

      Зашел, чтобы найти этот ответ.
      Плюс, создалось впечатление, что в статье будут рассказывать о Plan 9(в англйиской вики подробнее)


    1. dzavalishin
      01.05.2016 00:26

      open( "/dev/tcp/google.com/80") ведь не пройдёт, это ж в шелле зашит симулякр. Или я ошибаюсь?


      1. ValdikSS
        01.05.2016 00:37
        +3

        Не ошибаетесь. Еще есть подобная функциональность в zsh, только гораздо круче:
        http://zsh.sourceforge.net/Doc/Release/TCP-Function-System.html


      1. farcaller
        01.05.2016 12:35
        +1

        Ну так есть же connect, в чем смысл менять стандартный набор API на текстовый интерфейс /dev/host/port?


        1. dottedmag
          01.05.2016 12:50

          Вопрос «стандартности» не так прост.

          Если бы plan9 стал мейнстримом, то мы бы сейчас кривили рожу на «нестандартный» connect.


        1. dzavalishin
          01.05.2016 13:18

          смысл в том, что тогда все программы Юникса могут работать с сокетами. а не только специально описанные. регулярный интерфейс лучше.


          1. farcaller
            01.05.2016 13:50
            +2

            "Все программы Юникса" умеют работать с fd, так что можно отлично пайпить через nc, curl, socat, в конце концов. Разве с этим была какая-то проблема? API чтения и записи унифицированы.


            1. dzavalishin
              02.05.2016 01:17

              cat header /tcp/weather1.site divider /tcp/weather1.site footer >weather.html
              куда fd засовывать?


              1. farcaller
                02.05.2016 10:46
                +3

                cat header <(nc weather1.site) divider <(nc weather1.site) footer >weather.html


                1. dzavalishin
                  03.05.2016 01:51
                  +2

                  Вы знаете, мне удивительно, что это надо объяснять, но Юникс — это не шелл.

                  Мне совершенно непонятно, почему я не могу сделать file/open в произвольной программе и набрать в качестве имени файла ftp://… или http://, потому что задача ОС — виртуализировать реальность и представлять её программам в униформном виде. И когда мне всерьёз говорят — не надо унификации в ядре, лучше мы поддержим сто разных протоколов в тысяче разных программ ручками, я слегка офигеваю.

                  Зачем?? Ну вот тупо — зачем нужно иметь socket/connect, если всё то же самое можно сделать через open? Я ещё понимаю (и то умеренно) зачем listen/accept — на реально большом потоке входящих парсить строку имени файла дорого (да и так ли дорого, надо посмотреть ещё). Но есть масса тривиальных программ, которые нуждаются в элементарной работе с сетью на уровне палки и верёвки.

                  Мало того, реализация этого в ядре — 20 строк кода на всё. Ну тупо позвать из open socket и connect, всё. Люди получили бесплатную единообразность.


                  1. steamoor
                    03.05.2016 08:23

                    А вот в этом случае я даже поддержу:
                    сделать прозрачным обращение к файлам через популярные сетевые протоколы — это было бы удобно.

                    vi ftp://server/file (с возможной записью обратно)
                    и да, я знаю что Vim это умеет внутри себя, речь про ядерные вызовы.
                    сейчас это делается с помощью FUSE и только с конкретным (определенным при монтировании) сервером.


                    1. qw1
                      03.05.2016 11:47
                      +2

                      И пароль к ftp будет знать любая программа (т.к. он вынуждено будет указан в ссылке), а не только root, под которым монтировали.


                      1. steamoor
                        03.05.2016 16:13

                        Когда вы обращаетесь к зашифрованному диску, знает ли программа пароль на его разблокирование?

                        аутентикация должна происходить на уровне ядра, и именно оно должно спрашивать пароль по запросу, если необходимо (или указано имя пользователя)


                        1. qw1
                          03.05.2016 17:19
                          +1

                          Для зашифрованного диска пароль указывается при монтировании.

                          аутентикация должна происходить на уровне ядра, и именно оно должно спрашивать пароль по запросу, если необходимо

                          Вы не шутите? Ядро из какой-то своей зарытой глубины ядерного вызова должно понять, от какого юзера пришёл запрос, найти его сессию и в ней создать элемент интерфейса, чтобы спросить пароль? Учитывая все сценарии (текстовая консоль, графическая консоль, ssh-терминал)?


                          1. steamoor
                            03.05.2016 17:34

                            Если нужна аутентификация, то все что должно сделать ядро — вернуть запрос на пароль, что с этим будет делать приложение — это уже задача приложения. По аналогии с ssh и его agent.
                            Аутентификация может быть разная, по паролю, ключу, kerberos и так далее. Не всё однозначно.
                            в Windows, например, все подобные запросы обрабатываются на уровне explorer.exe. Не совсем ядро, но какой то единый слой, на который отсылаются все запросы.

                            Для простоты реализации, можно начать с публичных файлов, для который аутентификация не нужна.
                            Возможность просто сделать `${pdf_reader} http://server/file.pdf` будет шагом вперед.


                            1. qw1
                              03.05.2016 20:50
                              +1

                              Если нужна аутентификация, то все что должно сделать ядро — вернуть запрос на пароль, что с этим будет делать приложение — это уже задача приложения.

                              Это убьёт унификацию. Например, у меня обычная утилита копирования файлов. Но получила она SSL-ссылку на такой сервер, который требует клиентский сертификат. Так это что, моя утилита должна уметь не только вводить пароль, но и давать возможность выбирать файл сертификата? А может другой сервер захочет пруфов, что я умею готовить кофе? Или авторизацию по отпечаткам пальцев?
                              в Windows, например, все подобные запросы обрабатываются на уровне explorer.exe

                              Одно открытие за другим. Теперь explorer.exe предоставляет API для других приложений ))


                              1. steamoor
                                03.05.2016 21:10

                                Аутентификация это непростой процесс, я согласен. И утилиты, которые с этим работают, так же как они знают как работать с файлами и давать ядру комманду на открытие файла или любого другого девайса/порта они должны будут знать как работать с аутентификацией. Упрощения для разработчиков тут не будет, это точно.

                                Поэтому, давай откатимся назад к

                                >Для простоты реализации, можно начать с публичных файлов, для который аутентификация не нужна.
                                > Возможность просто сделать `${pdf_reader} http://server/file.pdf` будет шагом вперед.

                                Мне сейчас именно этого функционала не хватает. Когда у меня есть ссылка на файл и вместо того чтобы делать:
                                `wget http://server/file.deb; dpkg -i file.deb; rm -f file.deb`
                                я бы хотел делать `dpkg -i http://server/file.deb`
                                и чтобы это было не конкретная частная фича программы dpkg, а ядро откликалось на подобные запросы и возвращало файл. Это хотелка, и я этого не скрываю. Я уже вижу сколько подводных камней тут будет. И индивидуальные настройки прокси и прочие прочие прочие.

                                И да, я, возможно, погорячился с explorer.exe, понимание его механизмов у меня чисто интуитивное :)


                                1. qw1
                                  03.05.2016 21:20
                                  +2

                                  Хотелка понятная, но для неё надо весь unix вдоль и поперёк перепилить, простым костылём на open не отделаешься.

                                  Я думаю, ближе всего подошёл к этому Windows PowerShell с объектными пайпами.
                                  Объект с именем C:\file1.txt на самом деле не просто строчка, а некий интерфейс, который имеет свойства и методы. Также можно спланировать, чтобы http://xxx/xx имел сходный интерфейс и программы, которые принимают такие объекты через ком. строку, работали через интерфейсы этих объектов (смотрим, реализует IFileStream — давай с него почитаем байты, а если IFileName — назначим имя открываемому в редакторе документу, а если IFileSaveable, то и сохранение обратно разрешено)


                                  1. steamoor
                                    03.05.2016 21:26

                                    О, поверь мне, я против костылей.
                                    От деталей разработки и имплементации в ядре я, к сожалению, далёк. Могу помочь с логикой, тестированием.

                                    Я админ/архитектор/человек с кучей (не)обоснованных хотелок :)


                      1. loz
                        03.05.2016 20:02

                        Нет, пароль знать не будет, а лишь получит временный метадату от сервиса ключей, которую сможет использовать для установления соединения. Во всяком случае так происходит в plan9.


                        1. qw1
                          03.05.2016 20:54
                          +1

                          То есть, прежде чем я выполню vi ftp://server/file, мне надо к этому серверу ввести ключи в определённый сервис. Недалеко ушли от монтирования ))


                          1. vadimr
                            04.05.2016 00:14
                            +1

                            Ну почему? Произошло обращение к ftp://server/file. С сервера в ядро (или кто там обрабатывает вызов open) вернулся запрос на логин. Ядро запросило логин у сервиса ключей. Сервис ключей нашёл у себя – отдал / не нашёл у себя – выдал окошко или текстовое приглашение пользователю – отдал.

                            Принципиальной проблемы тут нет.


                            1. qw1
                              04.05.2016 08:03
                              +1

                              А если из cron запущено, в чьей сессии появится окошко?


                              1. vadimr
                                04.05.2016 08:50

                                Ни в чьей не появится, ошибка аутентификации вернётся. Точно так же, как если вызвать ftp из крона.


                                1. qw1
                                  04.05.2016 22:47

                                  В Windows есть объекты WindowStation и набор Desktop-ов в ней, в linux это есть на уровне оси или только на уровне графических оболочек?


                        1. qw1
                          03.05.2016 21:10

                          Да, кстати у такого подхода есть большой минус по сравнению с тем же wget: невозможно скачать с одного сервера с разными аутентификационными данными.

                          wget запустил параллельно с разными ключами логина/пароля, и качай.
                          тут же — зарегистрировал в сервисе пароль к серверу, сделал cp /dev/ftp/... myfile, разрегистрировал пароль, зарегистрировал новый пароль… Короче, костыль, как глобальные переменные в программировании.


                          1. vadimr
                            04.05.2016 00:15

                            cp user@ftp:…

                            Никто не мешает иметь несколько таких ссылок с разными пользователями активными одновременно.


                            1. qw1
                              04.05.2016 08:07
                              +2

                              так всё-таки user@ftp://server или /dev/ftp/server/…


                              1. vadimr
                                04.05.2016 08:49
                                -2

                                Какая разница? Это вопрос именования файлов в системе.


                                1. qw1
                                  04.05.2016 22:49

                                  В unix это предмет первостепенной важности.
                                  Корень обслуживает один код, по мере движения вниз подключается код из FS.
                                  А тут предлагается поломать эту схему.


                                  1. vadimr
                                    04.05.2016 22:52

                                    Ну в статье, вроде, Фантом обсуждается, а не юникс.


                                  1. dzavalishin
                                    04.05.2016 23:58

                                    ? Это детали. Очевидно, что втыкать в Юникс новую структуру именования файлов — некоторый избыточный авангард.

                                    mount -t tcpfs /tcp


                                    1. qw1
                                      05.05.2016 19:06

                                      Вопрос в том, с какой стороны к имени файла приклеить юзер/пароль/другие-аутентификационные-данные


                  1. qw1
                    03.05.2016 11:45
                    +2

                    Я думаю, тут загвоздка в параметрах, с которыми можно открывать сокет.
                    В сравнении nc vs /dev/tcp выигрывает nc, которому можно передать кучу опций.


                  1. mayorovp
                    03.05.2016 12:58
                    +2

                    Ну вот передам я ссылку «произвольной программе». В какой кодировке эта программа читать файл будет? Наверное, в системной… А в какой этот файл записан? В любой, сама кодировка приведена в заголовке Content-Type.

                    Так что, ядро теперь должно еще и перекодированием из windows-1251 в utf-8 заниматься?

                    Вот сижу и пытаюсь вспомнить, когда бы мне вдруг пригодилась возможность передать http-ссылку «произвольной программе» — и не могу. Ссылки я либо смотрел в браузере (уж эта программа точно должна обрабатывать http сама, кэш там, куки и прочее, что в формат /dev/http/… запихнуть сложно) — либо скачивал. Но та программа, которой надо открывать загруженный файл, определяется либо по заголовку Content-Type — либо по заголовку расширению, которое идет в заголовке Content-Disposition — то есть пока файл не скачаешь, с ним не понятно что делать.

                    Наконец, файл может быть большой — и лучше его скачать сразу, чем наблюдать как программа «тупит» при его чтении.

                    Вот и остается единственным сценарием, когда такой способ открытия файла применим — автоматизация, то есть тот самый шелл. В котором уже есть альтернативные механизмы.


                    1. vadimr
                      03.05.2016 13:54

                      Использование любых кодировок, кроме utf-8 – на сегодняшний день рудимент прошлого, и, как таковой, имеет значение только для специальных программ в специальных случаях.


                      1. mayorovp
                        03.05.2016 15:15
                        +1

                        Этот «рудимент» живее всех живых, и будет жить до тех пор, пока в книжках «изучаем PHP за день» не начнут писать про то, как переключить в тестовом редакторе кодировку.

                        Ну или пока виндовый Блокнот не начнет сохранять в UTF-8 по умолчанию.


                        1. vadimr
                          04.05.2016 00:18

                          Вопрос же не в том, чтобы в командной строке разбирать страницы сайтов из книжки “изучаем PHP за день”, которые, кстати, чуть менее, чем полностью состоят из ссылок на розовенькие гифчики и таблицы стилей. А в том, чтобы просто подцеплять содержимое обычных текстовых файлов, используя протокол http.


                    1. loz
                      03.05.2016 20:05

                      >В какой кодировке эта программа читать файл будет? Наверное, в системной…

                      Насколько я знаю, в Plan9 сервис предоставляющий интерфейс к http протоколу декодирует данные в системную (там юникод) кодировку используя этот заголовок.


                      1. qw1
                        03.05.2016 21:01

                        А что делать, если программа ожидает файл (т.е. возможность делать seek без каких-либо значимых затрат), а http-сервер на той стороне не поддерживает заголовок range (например, там PHP-скрипт, который пишет в stdout). Plan9 при каждом seek начинает читать файл каждый раз сначала или копирует в кеш и отдаёт байты оттуда? А если приложение захочет записать файл, но предварительно оригинал переименовать в *.bak, какой http-запрос сделает Plan9?


                        1. loz
                          04.05.2016 03:13

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

                          Вобще прикол плана не в этом, а в том, что можно делать сервисы которые предоставляют единый файловый интерфейс. И его удобство конечно зависит от того, как это смог сделать автор конкретного сервиса. А если на той стороне тупой php-скрипт, то что уж, с ним придется считаться, магии тут никакой нет.


                          1. qw1
                            04.05.2016 08:06
                            +2

                            Считаться с тупым скриптом кому? Если в linux это проблема только wget, то в Plan9 каждое приложение должно это учитывать?


                            1. loz
                              04.05.2016 08:45
                              -2

                              Я вот часто сомневаюсь, после таких вопросов, хабр это сайт для айтишников или домохозяек.


                  1. mayorovp
                    03.05.2016 13:00
                    +3

                    Мне вот куда чаще приходится с архивами работать. Давайте архиватор-разархиватор в ядро засунем? Чтобы можно было к архивам как к директориям обращаться! И чтобы поддерживал форматы zip, 7z, rar и cab. И про кодировку имен файлов не забыть…


                    1. dottedmag
                      03.05.2016 15:00
                      +1

                      FUSE


                      1. mayorovp
                        03.05.2016 15:14

                        Почему как архивы — так сразу FUSE, а как tcp или http — так в ядро?


                        1. dottedmag
                          03.05.2016 15:16

                          Ну так и TCP можно через FUSE.


                          1. mayorovp
                            04.05.2016 10:27

                            Ну так автор статьи-то в ядро засунуть его готов


                            1. dzavalishin
                              04.05.2016 13:30

                              Это вопрос технический. Конечно, ядро Линукса уже распухло до неприличия и сервисы из него надо выносить мешками.


                  1. loz
                    03.05.2016 20:10

                    Это, как уже написали ниже, требует много кода в сисколлах. В Плане действительно можно делать file/open на все, но не он реализует специфичную логику, а сервис, предоставивший к ресурсу файловый интерфейс.


                    1. dzavalishin
                      04.05.2016 13:31

                      Что логично.


  1. pansa
    30.04.2016 22:06
    +3

    Больше месяца прошло, а AXFR на вашем DNS так и не закрыли. А я уже даже ваших админов нашел и написал им лично. Видимо, до таких «мелочей» руки тоже не доходят =)


  1. pfactum
    30.04.2016 22:27

    Отлично ложится на идею трансляторов GNU Hurd :).


  1. hx0
    30.04.2016 23:47
    +4

    Есть ещё одна вещь, которой нет в современном Юниксе

    Для этого nc не подойдёт?

    На одном компьютере можно запустить:
    $ nc -l host port > local_file

    На другом:
    $ nc host port < local_file


    1. dzavalishin
      01.05.2016 00:27

      затычка же.


      1. mayorovp
        01.05.2016 09:38
        +5

        Не «затычка», а «unix-way»


        1. dzavalishin
          01.05.2016 13:18

          тогда почему cat >/dev/tty, а не cat | devttydriver?


          1. steamoor
            02.05.2016 01:00
            +3

            я думаю, потому что с файлами и их потоками все намного однозначнее, чем с сетевыми.

            в случае с «nc» можно открыть одно соединение и остальные будут отвергаться. Соответственно запишется только одна сессия.

            Что будет происходит с «cat /tcp/host/port» при нескольких клиентах? Ведь в общем случае в char или block девайс, на который натравливается cat, могут писать больше одной программы. А что если кто то уже слушает на этом порту?

            За счёт того, что есть все эти неоднозначности, какая то конкретная реализация будет частным решением, не покрывающим все возможности. Когда как существующие инструменты вполне даже покрывают все use case'ы.

            Я, честно говоря, не вижу практического применения для этого функционала. Засунуть в ядро сервер, который будет слушать на рандомном порту и выдавать входящую информацию на стандартный вывод? Для этого уже есть специализированные приложения типа «nc». Всё что делает ядро в этом случае это разрешает или нет открыть данный порт и разруливает права.


            1. loz
              03.05.2016 20:16
              -2

              >Что будет происходит с «cat /tcp/host/port» при нескольких клиентах? Ведь в общем случае в char или block девайс, на который натравливается cat, могут писать больше одной программы.

              Каждый будет читать из свого /tcp/host/port.

              >Ведь в общем случае в char или block девайс

              В общем случае эта разница пришла к нам из 70х, и в наше время такое легаси ненужно.


              1. steamoor
                03.05.2016 20:24
                +2

                > Каждый будет читать из свого /tcp/host/port.

                я вижу где у нас недопонимание:
                в моем случае `cat tcp/[ip]/port` выполняет что то вроде `tcpdump`, выводя данные, которые были посланы на локальный ip и port. то есть сервер
                в твоём случае — это клиенты, которые обращаются к внешним ресурсам.
                Оба случая валидны и не противоречат друг другу.

                > В общем случае эта разница пришла к нам из 70х, и в наше время такое легаси ненужно.

                Это если думать про них как про legacy. А разница тут всё таки в типе доступа.
                Block device = random access
                Char device = sequential access

                Попробуй рандомно прочитать что то с магнитной ленты, tty, да того же IP потока? :)
                только последовательно.


                1. loz
                  03.05.2016 22:57

                  >Попробуй рандомно прочитать что то с магнитной ленты, tty, да того же IP потока? :) только последовательно.

                  Логично. Я точно помню что в плане было что-то сделано для унификации и избавления от множества устройств, но сходу не нагуглил.


  1. MacIn
    01.05.2016 00:44

    PKT_T_WrireRQ
    


    1. dzavalishin
      01.05.2016 13:22

      thanx


  1. sasha1024
    01.05.2016 17:40

    Не помешала бы ссылка на статью с описанием «что такое Фантом». Я-то нашёл, но если бы первое упоминание «Фантома» было ссылкой, было бы проще.


    1. dzavalishin
      02.05.2016 01:19

      логично, постараюсь не забывать


  1. mbait
    02.05.2016 01:27

    Видимо, это теперь модно. Практического применения я не вижу, в Linux есть socat(1).


    1. Wedmer
      02.05.2016 10:43

      С каки это пор socat стал частью ядра?


      1. Zolushok
        02.05.2016 14:46

        а зачем оно в ядре? я так и не понял этого ни из статьи, ни из комментариев )

        для частных задач «перекачать файл через tcp на другую машину» есть прикладные утилиты вроде nc или socat.

        для другого класса задач есть множество сетевых fs.

        какую задачу решаем?


  1. Shamov
    03.05.2016 01:28

    Очень странная идея — соединить вместе универсальный транспортный протокол и универсальную концепцию иерархической файловой системы. Результат получится совершенно неуниверсальным. Такое скрещивание обычно делается на уровне приложения, когда уже известна конкретная прикладная задача. Причём между ними ещё вкорячивается какое-то специфичное внутреннее представление, которое с одной стороны хорошо отображается на файловую иерархию, а с другой — с минимальными издержками может быть преобразовано в форму, пригодную для транспортировки. Зачем такое делать в ОС? А если и делать, то почему только это? Почему бы ещё не сделать в ядре тривиальную БД? Я бы не отказался иметь возможность делать «cat /sql/Northwind/Customers | grep Moscow».


    1. dzavalishin
      03.05.2016 01:33

      Тут хорошо бы не смешивать интерфейс ОС, которым является не шелл, а слой системных вызовов, и реализацию ОС. Которая склоняет к тому, чтобы всё пихать в ядро.

      Сам по себе POSIX устарел жутко — нормальным современным интерфейсом для прикладной программы, конечно, давно служит Java class lib (ну или менее богатые, но всё равно объектные интерфейсы иных ЯП), но там, где POSIX вполне применим — для доступа к байт стримам — не применять его странно. В этом смысле для работы с БД он подходит фигово, хотя, с другой стороны, выдать таблицу как входной поток для awk — почему нет.

      tcp же реально активно применяется в скриптинге. актуально.


      1. Shamov
        03.05.2016 09:24
        +3

        Если TCP активно применяется в скриптинге, то это ещё не повод делать так, чтобы стандартные системные вызовы прозрачно работали с TCP-потоками как с файлами. Нужно просто сделать специальный шелл для TCP-скриптинга или специальную команду для скриптинга в стандартном шелле. Так же, как сделано, например, в DB2. Есть одна команда — db2, которая позволяет работать с сервером из командной строки. Можно писать в шелле почти на чистом SQL:

        db2 select * from Customers where City = 'Moscow';

        (Любители чистоты могут даже сделать алиасы типа: alias select=db2 select)

        Идея мне кажется странной не потому, что это неактуально. Просто я думаю, что при всей актуальности так всё равно не надо делать. Высокоуровневые прикладные задачи нужно решать на более высоком уровне, чем API операционной системы. На уровне API пусть решаются только низкоуровневые задачи. Такой подход предотвратит постепенное превращение ОС в сервер приложений а-ля Tomcat.


        1. Zolushok
          04.05.2016 01:02
          +1

          во, очень здравый комментарий. стандартизация на уровне ядра работы с сокетами как с файлами в итоге неизбежно приведет к запихиванию в ядро одной из существующих сетевых fs (или к изобретению новой). а зачем — таки-непонятно.


    1. Duduka
      03.05.2016 05:46
      +1

      Это уже давно реализовано «IBM System, AS/400»