Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I want to check whether or not a certain port is open (Haskell)?

I want to check whether or not a certain port is open on a certain host. How can I do that? After I've called connectTo and what's next, how can I actually know if a port is open?

main = do
  withSocketsDo $ do
    h <- connectTo "some_host.com" $ PortNumber 1234
    --- and....?
like image 485
Dorkajo Avatar asked Aug 25 '16 08:08

Dorkajo


People also ask

How to check if a port is open or not?

What to Know 1 Easiest: Open the Start menu > type command > right-click the Command Prompt app > Run as administrator. 2 Type netstat -ab > press Enter > look for items in the "LISTENING" state. 3 The alternative is to use a third-party app: We like TCPView, Nirsoft CurrPorts, and PortQry Command Line Port Scanner.

How to check open port using PowerShell TNS?

Checking open port using PowerShell tns is short for Test-NetworkConnection command. google.com is the host name. You can also put an IP address instead of the host name. You can specify the port number using the -port switch at the end of tnc command.

How do I know what port a program is using?

If you want to know the program's name that has a specific port open, then type netstat -aon and press Enter. This command will show the protocol the app is using, the local and remote IP addresses, and most importantly, the PID of the application using that port (the number on the far right). Remember to look for the LISTENING status.

How to check if port 8080 is open or not?

2.Type the command "netstat -an" to obtain a list of all the open ports. 3.Type the command "netstat -an | grep 8080" to determine whether port "8080" is open. You can replace "8080" with any specific port that you are looking for.


2 Answers

The main task here is to connect to call connect and capture exactly the case that the host refused the connection (as opposed to the host not existing or being unroutable).

A solution using the new Network.Socket API, not the deprecated Socket module, using the unliftio package's for async exception handling safety (you can use Control.Exception instead, but it will be less safe):

import           Data.Word (Word8)
import           Foreign.C.Error (Errno(..), eCONNREFUSED)
import           GHC.IO.Exception (IOException(..))
import           Network.Socket (PortNumber, socket, connect, close', Family(AF_INET), SocketType(Stream), SockAddr(SockAddrInet), tupleToHostAddress)
import           UnliftIO.Exception (try, bracket, throwIO)


-- | Checks whether @connect()@ to a given TCPv4 `SockAddr` succeeds or
-- returns `eCONNREFUSED`.
--
-- Rethrows connection exceptions in all other cases (e.g. when the host
-- is unroutable).
isPortOpen :: SockAddr -> IO Bool
isPortOpen sockAddr = do
  bracket (socket AF_INET Stream 6 {- TCP -}) close' $ \sock -> do
    res <- try $ connect sock sockAddr
    case res of
      Right () -> return True
      Left e ->
        if (Errno <$> ioe_errno e) == Just eCONNREFUSED
          then return False
          else throwIO e


-- | Creates a `SockAttr` from host IP and port number.
--
-- Example:
-- > simpleSockAddr (127,0,0,1) 8000
simpleSockAddr :: (Word8, Word8, Word8, Word8) -> PortNumber -> SockAddr
simpleSockAddr addr port = SockAddrInet port (tupleToHostAddress addr)

Then you can do:

> isPortOpen (simpleSockAddr (127,0,0,1) 8000)
True

Full module in this gist.

like image 134
nh2 Avatar answered Oct 08 '22 17:10

nh2


If connectTo returns, then the port is open. Otherwise it will throw exceptions like

*** Exception: connect: failed (Connection timed out (WSAETIMEDOUT))

or

*** Exception: connect: failed (Connection refused (WSAECONNREFUSED))

So you could do

import Network(connectTo, PortID(..), PortNumber(..))
import Control.Exception(try, SomeException)
import System.IO(Handle)

isPortOpen :: String -> PortNumber -> IO Bool
isPortOpen host port = do
  h <- try $ connectTo host (PortNumber port) :: IO (Either SomeException Handle)
  return $ case h of
    Left _ -> False
    Right _ -> True
like image 45
V. Semeria Avatar answered Oct 08 '22 17:10

V. Semeria