在保持连接打开的同时从套接字读取

时间:2015-07-07 21:32:35

标签: haskell networking

目前我有一些代码可以为某些测试目的创建服务器和客户端。

服务器代码

import Network.Socket
import Network.Socket.ByteString as NSB
import Network.Socket.ByteString.Lazy as NSBL
import Data.ByteString.Lazy as BSL
import Data.ByteString as BS
import Data.HashMap as HM
import System.IO as IO

main = withSocketsDo $ do
  sock <- socket AF_INET Stream 0
  setSocketOption sock ReuseAddr 1
  bindSocket sock (SockAddrInet (fromInteger 8585) iNADDR_ANY)
  listen sock 100
  servLoop sock

servLoop sock = do
  client = accept sock
  IO.putStrLn "Got a connection"
  h <- SocketToHandle client ReadWriteMode
  hSetBuffering h NoBuffering
  req <- BSL.hGet h 1024
  IO.putStrLn "Got some contents:"
  IO.putStrLn $ show req

客户代码

import Network.Socket
import Network.BSD
import Control.Monad
import System.IO as IO
import Data.Text as T
import Data.ByteString.Lazy as BSL
import Data.MessagePack as MP

main = withSocketsDo $ do
  sock <- socket AF_INET Stream 0
  setSocketOption sock ReuseAddr 1
  addr <- liftM hostAddresses $ getHostByName "localhost"
  connect sock $ SockAddrInet (fromInteger 8585) (Prelude.head addr)
  handle <- socketToHandle sock ReadWriteMode
  replicateM_ 5 $ BSL.hPut handle $ MP.pack ("Hello host" :: Text)
  hFlush handle
  getLine
  replicateM_ 5 $ BSL.hPut handle $ MP.pack ("Hello host" :: Text)
  hFlush handle
  hClose handle

观察到的行为是,在客户端调用hClose句柄之前,不会发送消息。但是,我希望保持句柄处于打开状态,以便快速发送更多请求并接收响应。我是以正确的方式来做这件事的吗?如果是这样,有没有办法保持句柄打开但是读取和写入套接字?

1 个答案:

答案 0 :(得分:1)

do r1 <- BSL.hGet h 1 rRest <- BSL.hGetNonBlocking h 1024 return (r1 BS.append rRest) 一直尝试读取,直到它有你所要求的字节数,即1024.你可能想要使用hGetNonBlocking。或类似的东西:

library(lubridate)

df1 <- data.frame(
  StartDate = as.Date(c("2015-07-01", "2015-06-01", "2015-07-15", "2015-08-01")),
  EndDate = as.Date(c("2015-09-30", "2015-10-31", "2016-01-31", "2015-12-31")),
  MonthlyRental = c(500, 600, 400, 800)
)

d <- c( as.Date("2015-07-31"),
        as.Date("2015-08-31"),
        as.Date("2015-09-30"),
        as.Date("2015-10-31"),
        as.Date("2015-11-30"),
        as.Date("2015-12-31"),
        as.Date("2016-01-31"),
        as.Date("2016-02-29")  )

RentPerDay <- outer( df1$"MonthlyRental", days_in_month(d), "/" )

countDays <- pmin( pmax( outer( d, df1$"StartDate", "-") + 1, 0 ), days_in_month(d) ) -
             pmin( pmax( outer( d, df1$"EndDate"  , "-"), 0 ), days_in_month(d) )

rentalIncome <- colSums( t(countDays) * RentPerDay )