I'll open with this: I know you can only have one TcpListener listening to any given port, I'm trying to find a way to work around this limitation.
I am attempting to build an application that supports another application on the same machine. The other application, which I have no control over, sends out a signal on a TCP Port when it opens or closes a study.
In order to accept this TCP signal, I built a Windows Tray Application that listens to that port, accepts the signal, and then processes the data that was transmitted to it. The code block that manages this Listener looks like this...
private TcpListener _tcpListener;
private Thread _listenerThread;
#region TCP Connection
public void StartListener()
{
if (_listenerThread != null)
StopListener();
_listenerThread = new Thread(RunListener);
_listenerThread.Start();
}
private void RunListener()
{
_tcpListener = new TcpListener(IPAddress.Any, this.TcpListenerPort);
_tcpListener.Start();
while (true)
{
Console.WriteLine(string.Format("Listening for connections on port {0}", this.TcpListenerPort));
try
{
TcpClient client = _tcpListener.AcceptTcpClient();
ThreadPool.QueueUserWorkItem(ProcessClient, client);
}
catch (SocketException ex)
{
// This occurs when we close the parent thread that runs the TcpListener because
// the TcpListener call to AcceptTcpClient is a blocking call.
}
catch (Exception ex)
{
Console.WriteLine(string.Format("Exception trying to AcceptTcpClient: {0}", ex.Message));
}
}
}
private void StopListener()
{
if (_tcpListener != null)
_tcpListener.Stop();
if (_listenerThread != null)
_listenerThread.Abort();
}
As you can see, this is pretty simple and straight-forward. I spool up a thread to hold the Listener, then wait for a signal to come through, then do something with the data that it sent me. And all of this is working just fine.
The problem comes from this: This tray application is set up to run when a user logs in to the machine. However, due to the 'One listener per port' rule of the TCP Listener, if more than one user logs on to the machine at once (either via VPN or through 'switching' rather than logging off), then a second instance of this application attempts to start. And promptly crashes because it attempts to listen to a port that is already being listened to.
I cannot change the way information is sent to me by the other program, and I cannot force Windows Users to properly log off before switching to a new user. I cannot relocate any of these pieces to a different machine, either. However, this tray-app needs to be available to each and every user.
I have quite run out of ideas for how to resolve this, and any input would be extremely helpful.
Specifically, I'm trying to locate a method to hijack an existing thread hosting a TcpListener, co-opting it for use by more than one Windows Account at a time on the same machine. Granted, I will certainly not turn down a better idea than the one I have, either.
EDIT: I have considered running it as a Service, but one of the outcomes of data being received by the Listener is that the Tray Application launches a web browser, and it has a user interface for configuring its settings.