Thursday, May 07, 2009

Check If Local Port Is Available For TCP Socket

From time to time we need to check if specified port is not occupied. It can be some sort of setup action where we install server product and want to assure that tcp listener will start without any problems.

How, to check if port is busy - start listening on it.

Version #1

bool IsBusy(int port)
{
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp);
try
{
socket.Bind(new IPEndPoint(IPAddress.Any, port));
socket.Listen(5);
return false;
} catch { return true; }
finaly { if (socket != null) socket.Close(); }
}
If another process is listening on specified address our code will return false. This will make our code think that port was free while it was not. Remember, we are checking port availability. We need exclusive access to the port.

Version #2
bool IsBusy(int port)
{
Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream,
ProtocolType.Tcp);
try
{
socket.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.ExclusiveAddressUse, true);

socket.Bind(new IPEndPoint(IPAddress.Any, port));
socket.Listen(5);
return false;
} catch { return true; }
finaly { if (socket != null) socket.Close(); }
}
This version of the code is much better. It tries to bind the endpoint with exclusive access. If some other process is listening on the port or established connection is bound to the port an exception will be thrown.

And, of course, there is another way how to perform the check. We shall use classes from System.Net.NetworkInformation namespace
bool IsBusy(int port)
{
IPGlobalProperties ipGP = IPGlobalProperties.GetIPGlobalProperties();
IPEndPoint[] endpoints = ipGlobalProperties.GetActiveTcpListeners();
if ( endpoints == null || endpoints.Length == 0 ) return false;
for(int i = 0; i < endpoints.Length; i++)
if ( endpoints[i].Port == port )
return true;
return false;
}