如何在Haskell中编写一个最小开销代理到localhost:3389? [英] How to write a minimal-overhead proxy to localhost:3389 in Haskell?
问题描述
更新:问题现在包含最终编辑答案!
我现在使用以下(最终答案):
I now use the following (final answer):
module Main where
import Control.Concurrent (forkIO)
import Control.Monad (when,forever,void)
import Network (PortID(PortNumber),listenOn)
import Network.Socket hiding (listen,recv,send)
import Network.Socket.ByteString (recv,sendAll)
import qualified Data.ByteString as B
import System
type Host = String
type Port = PortNumber
main :: IO ()
main = do
[lp,h,p] <- getArgs
start (port lp) h (port p)
where
port = fromInteger . read
start :: Port -> Host -> Port -> IO ()
start lp rh rp = withSocketsDo $ do
proxy <- listenOn $ PortNumber lp
forever $ do
(client,_) <- accept proxy
void . forkIO $ (client >-<) =<< rh .@. rp
(.@.) :: Host -> Port -> IO Socket
host .@. port = do
addr:_ <- getAddrInfo Nothing (Just host) (Just $ show port)
server <- socket (addrFamily addr) Stream defaultProtocol
connect server (addrAddress addr)
return server
(>-<) :: Socket -> Socket -> IO ()
x >-< y = do x >- y; y >- x
(>-) :: Socket -> Socket -> IO ()
s >- r = void . forkIO . handle $ forever stream
where
stream = recv s (64 * 1024) >>= ifNot0 >>= sendAll r
ifNot0 = \c -> do when (B.null c) $ handle (error "0"); return c
handle = flip catch $ \e -> print e >> sClose s >> sClose r
可以像这样运行:
proxy 2000 localhost 3389
如果使用mRemote连接到本地主机:2000,我做请参阅本地机器的登录屏幕! :)
Using mRemote, if I connect to localhost:2000, I do see the login screen of the local machine! :)
*如果我找到一种更进一步改进(> - )
的方法,我会更新它答案!
*If I find a way to improve (>-)
even further, I will update this answer!
推荐答案
看来你来到此tcp代理要点查找信息时。在这个时候,是坏了,有点凌乱。在这种情况下,请不要犹豫,平静作者(在这种情况下,我),以便他可以修复未来引用的要点:)
It seems that you came to this tcp proxy gist when looking for information. At this time, is is broken and a bit messy. In such case, please don't hesitate to ping the author (in this case, me) so that he can fix the gist for future references :)
我会尽快修复它并链接到这个SO问题。固定版本将包括sendAll以及来自这个SO问题的所有不错的建议,所以请分享你最好的想法。作为一个侧面说明,油门分支已经有了sendAll修复程序,以防感兴趣。
I'll fix it ASAP and link to this SO question. The fixed version will include sendAll as well as all nice suggestions coming from this SO question, so please share your best thoughts. As a side note, this branch of throttle already had the sendAll fix, in case of interest.
编辑:现在的要点是固定的
EDIT : the gist is fixed now
这篇关于如何在Haskell中编写一个最小开销代理到localhost:3389?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!