Never mind blocking. This is how you do it.
This code is excerpted from a custom control I wrote for an embedded
webserver. I use it to fulfil requests for addition resources like CSS or
images when I use an embedded webserver to render HTML. You can make it
pick a random port, and the widget exposes a LocalBaseUrl property that
tells your app the base URL for connecting to itself. That's what baseURL
is about.
Sockets aren't that hard but it takes a mind that's twisted in a special
way.
THIS CODE IS COPYRIGHT TO ME AND ANYONE PLANNING ON USING IT IN A
COMMERCIAL APPLICATION CAN JOLLY WELL PUBLICLY CREDIT ME.
The next Indian contractor to send a peremptory "UGENT: PLS HELP" message
to my private email address will receive pictures of dead cows in his
work inbox unless the request is accompanied by an offer to pay for my
time and trouble.
...
private TcpListener tcpListener;
private bool useRandomPort = true;
private int tcpListenerPort = 8080;
private bool shouldListen = false;
private Thread ListenerThread;
private string baseURL;
...
public void Start() {
if (useRandomPort)
tcpListenerPort = (new Random()).Next(16384,65535);
baseURL = "
http://localhost:" + tcpListenerPort + "/";
tcpListener = new TcpListener(IPAddress.Loopback,tcpListenerPort);
if ((VirtualRoots.Count>0) && (null==filesys))
filesys = new WebResourceProviderFileSystem();
shouldListen = true;
tcpListener.Start();
ListenerThread = new Thread(new ThreadStart(Listen));
ListenerThread.Priority = ThreadPriority.BelowNormal;
ListenerThread.Name = string.Format("{0} HTTP
Listener",this.GetType().ToString());
ListenerThread.Start();
}
public void Stop() {
shouldListen = false;
}
...
private void Listen(){
while (shouldListen) {
if (tcpListener.Pending()){
Socket socket = tcpListener.AcceptSocket();
socket.Blocking = false;
//Some applications disconnect immediately when just checking
//the continued presence of this app. These produce SelectError.
if (!socket.Poll(5000,SelectMode.SelectError)) {
//spawn another thread to handle this request
HttpRequestHandler handler = new
HttpRequestHandler(this,socket);
Thread newThread = new Thread(new ThreadStart(handler.Exec));
newThread.Name = string.Format("{0} request
handler",this.GetType().ToString());
newThread.Start();
}
} else
Thread.Sleep(200);
}
}