Как я могу получить информацию / примеры о Network.Socket {.ByteString}? - PullRequest
1 голос
/ 20 августа 2011

Я немного поиграл с сетевой библиотекой, «простой» формой, где использование довольно просто: комбинация «listenOn», «connectTo», «accept» и у нас что-то работает Теперь я пытаюсь использовать «реальную» вещь, то есть Network.Socket и Network.Socket.ByteString, потому что я хотел бы передавать файлы между клиентом и сервером. Но его не так просто использовать, как интерфейс более высокого уровня, и я ищу примеры кода и / или инструкции. В частности, код, имеющий дело с «getAddrInfo», «AddrInfo» и «SockAddr», я не очень глубоко понимаю.
Итак, где я могу получить этот тип ресурса?

Ответы [ 3 ]

1 голос
/ 21 августа 2011

Интерфейс .Socket представляет собой нечто большее, чем привязки к сокетам Беркли. Я предлагаю вам прочитать руководство Биджа по сетевому программированию (для C), чтобы разобраться с этим.

РЕДАКТИРОВАТЬ: Фраза "чуть больше, чем" не предназначена для того, чтобы уменьшить объем работы, необходимой для плавного конфигурирования, сборки и установки этого уровня на всех поддерживаемых платформах. Я просто говорю, что между многими операциями .Socket и страницами man (3) для примитивов C существует однозначное отношение.

1 голос
/ 21 августа 2011

Внизу документации приведен пример для модуля Network.Socket.ByteString.

0 голосов
/ 22 августа 2011

Я могу просто показать собственный пример:

import Network.Socket
  ( SocketType(..), AddrInfo(..), AddrInfoFlag(..), Family(..), socket, sClose, 
    defaultHints, withSocketsDo, connect, getAddrInfo, defaultProtocol )
import Network.Socket.ByteString( sendAll, recv )
import qualified Data.ByteString.Char8 as BC( readFile, hPut, null )

sendFile :: String -> Int -> FilePath -> IO Bool
sendFile server port filename = withSocketsDo $ do
  addrinfos <- getAddrInfo desiredAddr (Just server) (Just . show $ port)
  if null addrinfos
    then do
      return False
    else do
      datafile <- BC.readFile filename
      let serveraddr = head addrinfos
      sock <- socket (addrFamily serveraddr) Stream defaultProtocol
      connect sock (addrAddress serveraddr)
      sendAll sock datafile
      sClose sock
      return True

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

readerThread :: MyQueue -> Socket -> IO ()
readerThread queue serverSock = do
  (connsock, clientaddr) <- accept serverSock
  sClose serverSock
  putStrLn $ "> connected reader " ++ show clientaddr
  talk connsock
  sClose connsock
  putStrLn $ "> closed reader " ++ show clientaddr
  return ()
    where
      talk conn = do 
        msg <- recv conn 2048
        putStr $ "* get from " ++ show conn ++ "\n"
        myQueueWrite queue msg
        unless (B.null msg) $ do 
          talk conn

createInputPort :: ChildLocks -> MyQueue -> AddrInfo -> IO PortNumber
createInputPort children obuffer serverAddr = withSocketsDo $ do
  serverSock <- socket AF_INET Stream defaultProtocol
  bindSocket serverSock (addrAddress serverAddr)
  listen serverSock 1

  lock <- newChildLock children
  _ <- forkIO $ readerThread obuffer serverSock `finally` endChildLock lock
  socketPort serverSock

Y использовать собственную очередь (TCHAN) для связи между читателем сети потоком потребителя и childLocks для ожидания в конце с чем-то вроде waitForChildren children конструкции, которую я нашелstackoverflow.

ОБНОВЛЕНИЕ: waitForChildren в сообщении Сравнение потоков Haskell с потоками ядра - мой тест жизнеспособен?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...