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....?
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.
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.
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.
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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With