diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+0.1.0.23
+---------
+* Fix a bug to prevent a half closed connection to hold a file handle
+
 0.1.0.22
 --------
 * Add the `-o` flag to turn on simple obfuscation (randomly flush socket to vary
diff --git a/moesocks.cabal b/moesocks.cabal
--- a/moesocks.cabal
+++ b/moesocks.cabal
@@ -1,6 +1,6 @@
 name:               moesocks
 category:           Network
-version:            0.1.0.22
+version:            0.1.0.23
 license:            Apache-2.0
 synopsis:           A functional firewall killer
 description:        A socks5 proxy using the client / server architecture.
diff --git a/src/Network/MoeSocks/Helper.hs b/src/Network/MoeSocks/Helper.hs
--- a/src/Network/MoeSocks/Helper.hs
+++ b/src/Network/MoeSocks/Helper.hs
@@ -24,13 +24,14 @@
 import Prelude hiding (take, (-)) 
 import System.IO.Unsafe (unsafePerformIO)
 import System.Log.Logger
-import System.Random
 import System.Posix.IO (FdOption(CloseOnExec), setFdOption)
+import System.Random
 import System.Timeout (timeout)
 import qualified Data.ByteString as S
 import qualified Data.ByteString.Builder as B
 import qualified Data.ByteString.Lazy as LB
 import qualified Data.Strict as S
+{-import Data.List (isPrefixOf)-}
 
 
 -- BEGIN backports
@@ -150,7 +151,7 @@
 logWaitIO :: (Maybe String, IO a) -> IO ()
 logWaitIO x = do
   let _io = wrapIO x
-      aID = x ^. _1 & fromMaybe ""
+      aID = x ^. _1 . _Just 
 
   puts - "waiting for : " <> aID
   _io
@@ -173,20 +174,23 @@
 waitBothDebug :: (Maybe String, IO ()) -> (Maybe String, IO ()) -> IO ()
 waitBothDebug x y = do
   concurrently (logWaitIO x) (logWaitIO y)
-  let _xID = x ^. _1 & fromMaybe ""
-      _yID = y ^. _1 & fromMaybe ""
+  let _xID = x ^. _1 . _Just 
+      _yID = y ^. _1 . _Just
       _hID = _xID <> " / " <> _yID
   puts - "All done for " <> _hID
   pure ()
 
+{-connectTunnel :: (Maybe String, IO ()) -> (Maybe String, IO ()) -> IO ()-}
+{--- connectTunnel x y = finally (waitBothDebug x y) performGC-}
+{-connectTunnel = waitBothDebug-}
+
 connectTunnel :: (Maybe String, IO ()) -> (Maybe String, IO ()) -> IO ()
--- connectTunnel x y = finally (waitBothDebug x y) performGC
-connectTunnel = waitBothDebug
+connectTunnel x y = 
+  let _prolong _io = _io >> sleep 10
+  in
 
-{-connectTunnel :: (Maybe String, IO ()) -> (Maybe String, IO ()) -> IO ()-}
-{-connectTunnel x y = -}
-  {-withAsync (logWaitIO x) - const - do-}
-    {-logWaitIO y-}
+  race_ (_prolong - logWaitIO x) 
+        (_prolong - logWaitIO y)
 
 connectMarket :: (Maybe String, IO ()) -> (Maybe String, IO ()) -> IO ()
 connectMarket = waitBothDebug
@@ -258,17 +262,18 @@
 
 sendAllRandom :: Socket -> ByteString -> IO ()
 sendAllRandom aSocket aBuffer = do
-  _loop aBuffer
+  -- _lengthUpperBound <- randomRIO (1024, 4096)
+  _lengthUpperBound <- pure 2048
+  _loop _lengthUpperBound aBuffer
   where
-    _lengthUpperBound = 4096
-    _loop _buffer = do
-      _randomLength <- randomRIO (0, _lengthUpperBound)
+    _loop _bound _buffer = do
+      _randomLength <- randomRIO (0, _bound)
       {-_say - "randomLength: " <> show _randomLength-}
       let (_thisBuffer, _nextBuffer) = S.splitAt _randomLength _buffer
       sendAll aSocket _thisBuffer
       when (_nextBuffer & isn't _Empty) - do
         yield
-        _loop _nextBuffer
+        _loop _bound _nextBuffer
 
 sendBytes :: HQueue -> ByteString -> IO ()
 sendBytes _queue = atomically . writeTBQueue _queue . S.Just
@@ -330,7 +335,9 @@
       _produce :: Int -> IO ()
       _produce _bytesReceived = flip onException (f S.Nothing) - do
         _r <- timeoutFor aID aTimeout - recv_ aSocket
-        {-puts - "Get chunk: " <> (show - S.length _r) -- <> " " <> aID-}
+        {-when ("L" `isPrefixOf` aID) - do-}
+          {-_say - "Get chunk: " <> (show - S.length _r) <> " " <> aID-}
+        
         if (_r & isn't _Empty) 
           then do
             forM_ aThrottle - \_throttle -> do
