如何在Haskell中编写一个最小开销代理到localhost:3389? [英] How to write a minimal-overhead proxy to localhost:3389 in Haskell?

查看:245
本文介绍了如何在Haskell中编写一个最小开销代理到localhost:3389?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新:问题现在包含最终编辑答案!

我现在使用以下(最终答案):

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆