In C#, how to check if a TCP port is available?
Solution 1
Since you're using a TcpClient
, that means you're checking open TCP ports. There are lots of good objects available in the System.Net.NetworkInformation namespace.
Use the IPGlobalProperties
object to get to an array of TcpConnectionInformation
objects, which you can then interrogate about endpoint IP and port.
int port = 456; //<--- This is your value
bool isAvailable = true;
// Evaluate current system tcp connections. This is the same information provided
// by the netstat command line application, just in .Net strongly-typed object
// form. We will look through the list, and if our port we would like to use
// in our TcpClient is occupied, we will set isAvailable to false.
IPGlobalProperties ipGlobalProperties = IPGlobalProperties.GetIPGlobalProperties();
TcpConnectionInformation[] tcpConnInfoArray = ipGlobalProperties.GetActiveTcpConnections();
foreach (TcpConnectionInformation tcpi in tcpConnInfoArray)
{
if (tcpi.LocalEndPoint.Port==port)
{
isAvailable = false;
break;
}
}
// At this point, if isAvailable is true, we can proceed accordingly.
Solution 2
You're on the wrong end of the Intertube. It is the server that can have only one particular port open. Some code:
IPAddress ipAddress = Dns.GetHostEntry("localhost").AddressList[0];
try {
TcpListener tcpListener = new TcpListener(ipAddress, 666);
tcpListener.Start();
}
catch (SocketException ex) {
MessageBox.Show(ex.Message, "kaboom");
}
Fails with:
Only one usage of each socket address (protocol/network address/port) is normally permitted.
Solution 3
When you set up a TCP connection, the 4-tuple (source-ip, source-port, dest-ip, dest-port) has to be unique - this is to ensure packets are delivered to the right place.
There is a further restriction on the server side that only one server program can bind to an incoming port number (assuming one IP address; multi-NIC servers have other powers but we don't need to discuss them here).
So, at the server end, you:
- create a socket.
- bind that socket to a port.
- listen on that port.
- accept connections on that port. and there can be multiple connections coming in (one per client).
On the client end, it's usually a little simpler:
- create a socket.
- open the connection. When a client opens the connection, it specifies the ip address and port of the server. It can specify its source port but usually uses zero which results in the system assigning it a free port automatically.
There is no requirement that the destination IP/port be unique since that would result in only one person at a time being able to use Google, and that would pretty well destroy their business model.
This means you can even do such wondrous things as multi-session FTP since you set up multiple sessions where the only difference is your source port, allowing you to download chunks in parallel. Torrents are a little different in that the destination of each session is usually different.
And, after all that waffling (sorry), the answer to your specific question is that you don't need to specify a free port. If you're connecting to a server with a call that doesn't specify your source port, it'll almost certainly be using zero under the covers and the system will give you an unused one.
Solution 4
Thanks for this tip. I needed the same functionality but on the Server side to check if a Port was in use so I modified it to this code.
private bool CheckAvailableServerPort(int port) {
LOG.InfoFormat("Checking Port {0}", port);
bool isAvailable = true;
// Evaluate current system tcp connections. This is the same information provided
// by the netstat command line application, just in .Net strongly-typed object
// form. We will look through the list, and if our port we would like to use
// in our TcpClient is occupied, we will set isAvailable to false.
IPGlobalProperties ipGlobalProperties = IPGlobalProperties.GetIPGlobalProperties();
IPEndPoint[] tcpConnInfoArray = ipGlobalProperties.GetActiveTcpListeners();
foreach (IPEndPoint endpoint in tcpConnInfoArray) {
if (endpoint.Port == port) {
isAvailable = false;
break;
}
}
LOG.InfoFormat("Port {0} available = {1}", port, isAvailable);
return isAvailable;
}
Solution 5
TcpClient c;
//I want to check here if port is free.
c = new TcpClient(ip, port);
...how can I first check if a certain port is free on my machine?
I mean that it is not in use by any other application. If an application is using a port others can't use it until it becomes free. – Ali
You have misunderstood what's happening here.
TcpClient(...) parameters are of server ip and server port you wish to connect to.
The TcpClient selects a transient local port from the available pool to communicate to the server. There's no need to check for the availability of the local port as it is automatically handled by the winsock layer.
In case you can't connect to the server using the above code fragment, the problem could be one or more of several. (i.e. server ip and/or port is wrong, remote server not available, etc..)
michelleedward
Updated on November 26, 2020Comments
-
michelleedward over 3 years
I am busy coding a program in netbeans (java)for a school project. It has multiple JFrames. I just figured out how to make each frame full screen, but now all the elements are in the wrong places. What do I do? Is there a way for me to make sure that the elements are fixed and don’t move? Thank you
-
Ali over 15 yearsI am the one trying to connect to a socket. I have edited the question to make it more clear.
-
Ali over 15 yearsI am using .NET 3.5 and I can't fine that.
-
Ali over 15 yearsIf my application try to connect using port 10 and another instance of my application try to connect using port 10 again it will fail because both applications can't send data using one port, when it comes to receiving data i.e. port 80 that is different
-
Moose over 15 yearsif it fails when the second instance tries to connect, it is the listening application, not your application.
-
Moose over 15 yearsThat's where I was going with it too. Someone is definitely confused here, and it's possible it me.
-
jro about 15 yearsGood point, very possible. Not sure one can lock or mutex their way to exclusive access to a port.
-
Dave Van den Eynde about 15 yearsIt is possible that the client requires a certain port too, but it's not common.
-
user772401 about 15 yearsHow is this relevant to the question? This answer deals with local ports, not remote ports.
-
jro about 15 yearsIt's relevant in that it answers the OP's request. The local/remote difference notwithstanding (totally agree with you), the OP's requirement was to create a new TcpClient with a port that is "free".
-
JoeBilly almost 13 yearsNote that this code only check active connections. The connections which don't have sent or received packets will not be listed.
-
Mike de Klerk over 11 yearsCompare the result of the code above to
netstat -a -b
. Notice thatLISTENING
connections are not present in theGetActiveTcpConnections()
. You should also check inSystem.Net.IPEndPoints[]
returned byipGlobalProperties.GetActiveTcpListeners();
-
Csaba Toth about 11 yearsThat is good for checking a set of given sockets. The question is about just one socket (which port number maybe undetermined though (?))
-
Csaba Toth about 11 yearsI like this code the best, this really opens up a TCP connection to a socket just to peek if someone is listening on the other end or not. And I think many people actually want this, when they want to "test if a port is open on a remote host". There is a bug however in the above code: if (sock.Connected == true) then the port is open for connections, some server-like software is listening there. If there's a SocketException with a 10061 ErrorCode (message "(0x80004005): No connection could be made because the target machine actively refused it" then the port is closed!
-
Csaba Toth about 11 yearsSo it's the other way around then in the code snippet. Another note: if someone would try Dns.GetHostEntry in such test setup where you have virtual servers with only IP addresses, you gonna have an exception.
-
Csaba Toth about 11 yearsTOCTOU is YALAIHHOBIKTPBI (Yet Another Long Abbreviation I Haven't Heard Of, But I Know the Phenomena Behind It)
-
user207421 about 9 yearsYou can create a TcpClient with a local port that is free by specifying zero as the local port. None of this is necessary, and it is liable to a major timing-window problem.
-
user207421 about 9 yearsYou don't need this. Just specify port zero.
-
user207421 about 9 yearsJust try to listen on it yourself. You don't need any of this.
-
Glubus over 8 yearsWhen posting some code, try to elaborate on why it is the solution to the problem. Just code might be too little information and your answer risks being looked over.
-
BrainSlugs83 over 8 years@jro -- the
TcpClient
class will always use a port that is free (the port in the constructor that the op asked about is for the remote endpoint! -- local outgoing ports are always auto assigned by winsocks, and you do not have control over them!). -- This is useful forTcpServer
, etc. -- but I'm not sure how useful it will be for whatever the heck the op is trying to do. -
BrainSlugs83 over 8 years@DaveVandenEynde that can only happen if the "client" is actually "serving" something on that particular port (making it a "server", at least for that port, as far as TCP is concerned). -- When you have a client TCP connection, you don't get to control the outgoing port. The TCP stack assigns you an outgoing port, and you don't have any control over it.
-
Dave Van den Eynde over 8 years@BrainSlugs83 You most certainly can: stackoverflow.com/questions/2869840/…
-
Kraang Prime about 7 yearsThe note in the source code comment : "This is the same information provided by the netstat command line application" -- is a lie. It does not provide the same information as the netstat command also provides the PID of the application using the port (
-anb
) and without any parameters it shows Foreign connection as well as state. -
bgh over 4 yearsThis is a valid bit of code to check if the port is free. Just remember to Stop() the TcpListener in case it succeeds (unless you intend to use that same TcpListener object to start listening on the port).