Socket. Сеть

  Пример чтения главной страницы сайта mysite.org :

(nil  let ((s ('socket  newobject)))
  (s  connect 80  "mysite.org")
  (s  write (("GET /index.html HTTP/1.1"  + (13 char) (10 char)
        "Host: mysite.org"  (13 char) (10 char)
        (13 char) (10 char))  byte-vector))
  (nil  let (buf  (bufsize 1024)  res)
    (nil  setq  buf ('byte-vector newobject bufsize))
    (nil do-while
      (nil  setq  res (s  read  buf bufsize))
      (nil  if  (nil  numberp res)
        (nil  progn
          (res  for*  i
            (cout write ((buf elt i)  char)))
          (res  > 0))
        (nil  progn
          (cout writeln "Error: " res)
          false))))
  (s  close))

  Подключение используя порт 80 к сайту mysite.org. Посылка пакета данных, с синтаксисом и порядком HMTL стандарта. Чтение ответных пакетов, до тех пор пока эти пакеты не пустые. Закрытие связи.

  Для сетевого взаимодействия внутри системы используют сокеты UNIX. В файловой системе используется файл как точка связи. Но передача данных происходит через буферы.

(nil  let ((socketname  (nil  const "Мой Сокет"))
    (lockcout ('lock  newobject)))
  (nil  let ((unlink-error  (socketname unlink)))
    (nil  if  unlink-error
      (cout writeln "unlink(" socketname  ")="  unlink-error)
      (cout writeln "unlink(" socketname  ")=OK"))) ; let unlink-error
  (nil  fork
    (nil  try
    ; Клиент
    (nil  let ((sc  ('socket  newobject)) o s c)
      (sc open  "UNIX"  "STREAM")
      (lockcout progn (cout writeln "Клиент: open = " o))
      (nil  let (ce)
        (nil  do-while
          (lockcout progn (cout writeln "Клиент: connect..."))
          (nil  setq  ce  (sc connect socketname))
          (nil  if  ce
            (nil  progn
              (lockcout progn (cout writeln "Клиент connect: " ce))
              (1  sleep))
            (lockcout progn (cout writeln "Клиент connect: OK")))
          ce) ; do-while
        ) ; let ce
      (lockcout progn (cout writeln "Клиент посылает сообщение серверу: Привет!"))
      ('s set (sc write "Привет!"))
      (lockcout progn (cout writeln "Клиент послал "  s " байт"))
      (nil  let ((buf ('byte-vector newobject 100)) r)
        ('r set (sc read  buf))
        (lockcout progn (cout writeln "Клиент получил сообщение размером "  r))) ; let buf
      ('c set (sc close))
      (lockcout progn (cout writeln "Клиент закрыл  связь с сервером : " c))) ; let sc клиент
    nil
    (nil  progn 
      (cerr writeln "Клиент:EvalHistory[") 
      ((nil  exception-history) for*  history-i 
        (cerr print history-i)) 
      ((cerr writeln "]")  
        write "Error: ")  
      (nil  let ((exv (nil  exception)))  
        (nil  if  (nil  consp exv)  
          (nil  apply cerr  'writeln  exv)  
          (cerr writeln exv)))
      nil)
    ) ; try
    ) ; fork
  ; Сервер
  (nil  let ((sc  ('socket  newobject)) l b o a s u c c2)
    ('o set (sc open  "UNIX"  "STREAM"))
    (lockcout progn (cout writeln "Сервер: open = " o))
    (sc bind  socketname)
    (lockcout progn (cout writeln "Сервер: bind = " b))
    (lockcout progn (cout writeln "Сервер: socket-max-connections = " socket-max-connections))
    ('l set (sc listen  socket-max-connections))
    (lockcout progn (cout writeln "Сервер: listen = " l))
    ('a set (sc accept))
    (lockcout progn (cout writeln "Сервер: accept = " a))
    (nil  let ((buf ('byte-vector newobject 100)) r)
      ('r set (a  read  buf))
      (lockcout progn (cout writeln "Сервер получил сообщение размером "  r))) ; let buf
    (lockcout progn (cout writeln "Сервер посылает сообщение клиенту: Пока!"))
    ('s set (a  write "Пока!"))
    (lockcout progn (cout writeln "Сервер послал "  s " байт"))
    ('c2 set (a  close))
    (lockcout progn (cout writeln "Сервер закрыл  связь с клиентом : " c2))
    ('c set (sc close))
    (cout writeln "Сервер закрылся : " c)
    ('u set (socketname unlink))
    (cout writeln "Сервер удалил файл : " u)) ; let sc сервер
  ) ; let socketname

  Сначала удаляется сокет файл, иначе создать новый с тем же именем не выйдет. Запускаются два процесса, один как сервер другой - клиент. Клиент скорее всего быстро подключиться не сможет, поэтому запросы выполняются с циклом 1 секунда. Сервер создаёт сокет, включает приём запросов, принимает клиента, читает его сообщение и передаёт своё сообщение. После чего закрывает связь с клиентом, отключает себя и удаляет файл.
  Исключения, происходящие внутри клиента до сервера не дойдут, поэтому внутри клиента вписано захват исключений.
  Вот как может происходить данный процесс:

unlink(Мой Сокет)=NOENT
Клиент: open = nil
Клиент: connect...
Сервер: open = nil
Сервер: bind = nil
Клиент connect: CONNREFUSED
Сервер: socket-max-connections = 128
Сервер: listen = nil
Клиент: connect...
Сервер: accept = Socket(5)
Клиент connect: OK
Клиент посылает сообщение серверу: Привет!
Клиент послал 13 байт
Сервер получил сообщение размером 13
Сервер посылает сообщение клиенту: Пока!
Сервер послал 9 байт
Клиент получил сообщение размером 9
Сервер закрыл  связь с клиентом : nil
Клиент закрыл  связь с сервером : nil
Сервер закрылся : nil
Сервер удалил файл : nil