Чуть ранее мы написали простой TCP сервер. Теперь мы напишем простой клиент для него.
Наш клиент будет получать сообщение со стандартного входа (клавиатура), отправлять его на сервер и получать ответ. Все просто.
Уже знакомый нам импорт:
Тут-то и комментировать нечего. Вопросы возникают только с этими строчками:
Наш клиент будет получать сообщение со стандартного входа (клавиатура), отправлять его на сервер и получать ответ. Все просто.
Уже знакомый нам импорт:
import Network.Socket hiding (send, sendTo, recv, recvFrom) import Network.Socket.ByteString (send, recv) import qualified Data.ByteString.Char8 as B8 import System.Environment (getArgs)И сам клиент:
client :: String -> Int -> IO () client host port = withSocketsDo $ do addrInfo <- getAddrInfo Nothing (Just host) (Just $ show port) let serverAddr = head addrInfo sock <- socket (addrFamily serverAddr) Stream defaultProtocol connect sock (addrAddress serverAddr) msgSender sock sClose sock msgSender :: Socket -> IO () msgSender sock = do msg <- B8.getLine send sock msg rMsg <- recv sock 10 B8.putStrLn rMsg if msg == B8.pack "q" then putStrLn "Disconnected!" else msgSender sock
Тут-то и комментировать нечего. Вопросы возникают только с этими строчками:
addrInfo <- getAddrInfo Nothing (Just host) (Just $ show port)let serverAddr = head addrInfosock <- socket (addrFamily serverAddr) Stream defaultProtocol
Функция getAddrInfo имеет следующую сигнатуру:
:: Maybe AddrInfo | выбранный тип сокета или протокол |
-> Maybe HostName | Hostname машины |
-> Maybe ServiceName | имя службы (порт) для поиска |
-> IO [AddrInfo] |
Функция возвращает список, с лучший вариантом из найденного в начале. Либо пустой список.
Естественно нам нужен "лучший" вариант, поэтому мы не думая берем head:
let serverAddr = head addrInfoДля общения мы должны быть на одной волне, а именно - мы должны использовать единый протокол.
Поэтому при создании сокета мы "вытягиваем" наименование протокола из найденного сервера:
sock <- socket (addrFamily serverAddr) Stream defaultProtocolДля запуска нашего клиента вызываем функцию client:
client "localhost" 3000Параметры естественно могут быть другими.
Функция main:
main = do [host', port'] <- getArgs client host' (read port' :: Int)И компиляция:
ghc -o client Client.hsБинарник запускается так: client "localhost" 3000
Вот и все. Клиент готов!
Весь код тут.
Комментариев нет:
Отправить комментарий