Программирование на языке Ruby.

18.1.1. Простой сервер: время дня.

Рассмотрим самый простой сервер, который вы только способны представить. Пусть некоторая машина располагает такими точными часами, что ее можно использовать в качестве стандарта времени. Такие серверы, конечно, существуют, но взаимодействуют не по тому тривиальному протоколу, который мы обсудим ниже. (В разделе 18.2.2 приведен пример обращения к подобному серверу по протоколу telnet.).

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

Require "socket".

PORT = 12321.

HOST = ARGV[0] || 'localhost'.

Server = UDPSocket.open # Применяется протокол UDP...

Server.bind nil, PORT.

Loop do.

 text, sender = server.recvfrom(1).

 server.send(Time.new.to_s + "\n", 0, sender[3], sender[1]).

End.

А это код клиента:

Require "socket".

Require "timeout".

PORT = 12321.

HOST = ARGV[0] || 'localhost'.

Socket = UDPSocket.new.

Socket.connect(HOST, PORT).

Socket.send("", 0).

Timeout(10) do.

 time = socket.gets.

 puts time.

End.

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

В следующем примере такой же сервер реализован на базе протокола TCP. Он прослушивает порт 12321; запросы к этому порту можно посылать с помощью программы telnet (или клиента, код которого приведен ниже).

Require "socket".

PORT = 12321.

Server = TCPServer.new(PORT).

While (session = server.accept).

 session.puts Time.new.

 session.close.

End.

Обратите внимание, как просто использовать класс TCPServer. Вот TCP-версия клиента:

Require "socket".

PORT = 12321.

HOST = ARGV[0] || "localhost".

Session = TCPSocket.new(HOST, PORT).

Time = session.gets.

Session.close.

Puts time.