Suspend Sub-Process in .NET? - c#

I wrote a small daemon application in .NET last year that basically launches a Minecraft server, and provides a web based GUI to manage it. It does other things such as restart the process if it crashes, and other useful functions.
Our company recently heard of a french hosting company that had setup their servers in a way that when the last player disconnected, the server would shutdown until another player joined. Now, I have been thinking about how this might be possible, and wanted to see what the thoughts on it were. My daemon can already tell how many players are connected, so that is not an issue.
My psuedo thought process is...
Last Player disconnects from server
Daemon takes over listening on the server port for connections
Upon incoming connection, save the connection packet data and restart the server sub-process
Pass the save connection on to the Minecraft java process
I can't really figure out how to handle the last step yet, but that is the best solution I have come up with. Any thoughts or suggestions?

Perhaps you'll have more players wanting to connect at once, so you might have problems with that approach (cuz i'm guessing your server won't start instantaneously).
You should have a daemon waiting for connections and putting them on a queue or something, until the server starts, and feed it then, the connections (or connection packets or whatever). After the server is started, and all connections have been forwarded to it, get your daemon to "stop" (a.k.a die or stop clogging the port)
Hope this helps.

You can not "save" a TCP network connection and then redirect it to a different process. The only way to implement this would be to let your tool act as a proxy server that accepts all connections and sends all data to the server running on a different port.
In such a set-up you could start the server upon the first incoming connection.
The only other solution would require direct read access to the network interface the way e.g. is used by Wireshark/Pcap library. They you would be able to detect TCP SYN packets and start the server when they are coming in.

Related

CF app two way communications with server

Users in field with PDA's will generate messages and send to the server; users at the server end will generate messages which need to be sent to the PDA.
Messages are between the app and server code; not 100% user entered data. Ie, we'll capture some data in a form, add GPS location, time date and such and send that to the server.
Server may send us messages like updates to database records used in the PDA app, messages for the user etc.
For messages from the PDA to server, that's easy. PDA initiates call to server and passes data. Presently using web services at the server end and "add new web reference" and associated code on the PDA.
I'm coming unstuck trying to get messages from the the server to the PDA in a timely fashion. In some instances receiving the message quickly is important.
If the server had a message for a particular PDA, it would be great for the PDA to receive that within a few seconds of it being available. So polling once a minute is out; polling once a second will generate a lot of traffic and, maybe draim the PDA battery some ?
This post is the same question as mine and suggests http long polling:
Windows Mobile 6.0/6.5 - Push Notification
I've looked into WCF callbacks and they appear to be exactly what I want however, unavailable for compact framework.
This next post isn't for CF but raises issues of service availability:
To poll or not to poll (in a web services context)
In my context i'll have 500-700 devices wanting to communicate with a small number of web services (between 2-5).
That's a lot of long poll requests to keep open.
Is sockets the way to go ? Again that's a lot of connections.
I've also read about methods using exchange or gmail; i'm really hesitant to go down those paths.
Most of the posts i've found here and in google are a few years old; something may have come up since then ?
What's the best way to handle 500-700 PDA CF devices wanting near-instant communication from a server, whilst maintaing battery life ? Tall request i'm sure.
Socket communication seems like the easiest approach. You say you're using webservices for client-server comms, and that is essentially done behind the scenes by the server (webservice) opening a socket and listening for packets arriving, then responding to those packets.
You want to take the same approach in reverse, so each client opens a socket on its machine and waits for traffic to arrive. The client will basically need to poll its own socket (which doesnt incur any network traffic). Client will also need to communicate its ip address and socket to the server so that when the server needs to communicate back to the client it has a means of reaching it. The server will then use socket based comms (as opposed to webservices) to send messages out as required. Server can just open a socket, send message, then close socket again. No need to have lots of permanently open sockets.
There are potential catches though if the client is roaming around and hopping between networks. If this is the case then its likely that the ip address will be changing (and client will need to open a new socket and pass the new ip address/socket info to the server). It also increases the chances that the server will fail to communicate with the client.
Sounds like an interesting project. Good luck!
Ages ago, the CF team built an application called the "Lunch Launcher" which was based on WCF store-and-forward messaging. David Kline did a nice series on it (here the last one, which has a TOC for all earlier articles).
There's an on-demand Webcast on MSDN given by Jim Wilson that gives an outline of store-and-forward and the code from that webcast is available here.
This might do what you want, though it got some dependencies (e.g. Exchange) and some inherent limitations (e.g. no built-in delivery confirmation).
Ok, further looking and I may be closer to what I want; which I think i a form of http long poll anyway.
This article here - http://www.codeproject.com/KB/IP/socketsincsharp.aspx - shows how to have a listener on a socket. So I do this on the server side.
Client side then opens a socket to the server at this port; sends it's device ID.
Server code first checks to see if there is a response for that device. If there is, it responds.
If not, it either polls itself or subscribes to some event; then returns when it's got data.
I could put in place time out code on the server side if needed.
Blocking on the client end i'm not worried about because it's a background thread and no data is the same as blocking at the app level; as to CPU & batter life, not sure.
I know what i've written is fairly broad, but is this a strategy worth exploring ?

How to find all instances of a running program on all hosts on a LAN?

For practical purposes, what SqlDataSourceEnumerator does is find all instances of SQL server running on the various PCs on a LAN.
Is there an equivalent for finding running instances of an arbitrary application?
Edit: OK, so this only works because these apps have a pre-defined method of cooperation. Is there a straightforward way of determining if a given file (the exe, say) exists on some machine on the LAN even if the app itself itself is not running at the time? Understood that permissions must be taken into account.
What SQL enumeration does it broadcasts an UDP packet (port 1434) on the entire lan segment (subnet mask). The SQL Browser Agent service running on various hosts listens for this packet and responds with the list of local instances. So for the enumeration to happens, a number of ducks are already aligned for you:
there is a well know protocol for SQL isntance discovery, the UDP 1434 broadcast and response
there is a service listening for this broadcast, installed by SQL Server setup
there is a client library to implement the broadcast request formatting and response parsing which you leverage
For an arbitrary application to behave the same, the said application would have to implement these missing parts. Discovering arbitrary processes running on arbitrary hosts in a subnet segment is basically impossible for all practical means.
The difference is that SqlDataSourceEnumerator finds all instances "that it can see" on a LAN. If the server process is configured not to respond to that request, then it won't be seen.
Along that same line, you can scan for any application that has some way of making its presence known remotely. At its simplest, the application would be listening for and responding to connections. The application could, for example, bind to a TCP port and listen for any request and send back a response saying that it's alive and running, and hosts on a network can be scanned for those replies.
As for "an arbitrary application" however, most applications don't have such a mechanism for network discovery. If you control the arbitrary application then you can build that functionality into it. But if you do not then you'll need some way to look for that application on any given host, which means it'll need some kind of network interaction.
No, there isn't.
The reason that works for SQL server is that SQL server has a listener that listens on the network for "discovery" requests. An app can then send out a broadcast message on the network and listen for responses to that request to discover SQL server instances.
I suppose you could write a program that would do this generically though - It could listen for discovery requests, use some windows API functions to enumerate the processes running on that computer, and respond if the requested program is running.

Can I Wake On Lan my remote computer through a webservice?

I have an application which is running on a remote machine. The only contact with the application is through a webservice, i can send it a command to shut down - but how do i start it again? I would like to have a scheduling type of service where i have a windows service on my machine and at 08:00 am it sends a startup command through the webservice(??) and at 04:00 pm it sends a shutdown command through the webservice. The shutdown i can do, but the wake on lan thing - because its not a lan, its potentionally the internet - any suggestions?
cheers,
You won't be able to wake your remote machine up using a web service call to your actual machine you want to wake up. You will have to send it a 'magic' packet.
Luckily there are a bunch of tools and utilities out there that allow you to do this quite easily.
Check out wolcmd.exe - that should do the trick for you.
Equally, there's nothing stopping you rolling your own client that sends the magic packet, if you are so inclined.
And if you want to run this from a web service (not located on the target machine obviously), you simply wrap wolcmd.exe by using System.Diagnostics.Process.Start().
Here are two links that I googled on here and here. My take is that you'd need to connect to a remote lan via VPN passing through a firewall to be on the same subnet and similar ip address as where the webservice is running on! That should be secure enough and if you do that, only your machine can then be shut down remotely. My feeling is this - you'd need to be connected directly to the remote endpoint all the time...But at the top of my head, that sounds frankly impossible, as how will the remote endpoint know your ip address if your machine went to sleep...You need to be careful of certain drivers that will refuse to go to sleep and therefore preventing your machine from going to sleep. I happen to have a 3G mobile broadband, and my netbook refuses to sleep unless I shutdown the connection and unplug it (even if its still plugged in, it refuses to sleep!), the reason I say that, if you were to use VPN, and it went to sleep, then that connection is lost - that's my opinion of it. What do you think?
Hope this helps,
Best regards,
Tom.
If the web service is on a separate box on the same local LAN as the box which needs to be started, it should be possible to have a web service use Wake-on-LAN technology to start it.

Socket Dis-Connects On One End, Firewall?

I have a C# application that has been running fine for several years. It connects via a TCP/IP socket to a machine that sends me stock trade executions.
Recently, I've tried to deploy it to some machines in a new data center that is behind a hardware firewall, and I've started to see some weird dis-connects.
When a dis-connect happens, in my app (the client side), I see nothing unusual except that I stop receiving data over the socket. Wireshark confirms that no data is reaching the socket and my application's receive thread is blocking on the Receive() call when I stop it in the debugger. The socket shows as ESTABLISHED in netstat.
But from the server side, it looks like my client is dis-connecting. Looking at their logs, it looks like the socket on their end usually ends up with either (nRecvd=-1,errno=104) or (nRecvd=0,errno=11). (104 is connection reset by peer).
The dis-connect only seems to happen after a period of in-activity. I have solved this for now by implementing a heartbeat between my client and their server that just sends a short message every 20 seconds and gets a reply. This has caused the dis-connects to drop to 0 over the past few days.
At first, I figured that the hardware firewall was the problem. It was causing the socket to time out after in-activity. But the person in charge of the firewall claims that the timeout for connects on this port (8887) is 2160 minutes.
I am running Windows Server 2003 and .NET 3.5. The trades server is a linux machine (sles9 I believe though I'm not sure).
Any ideas on what might be going on? What could I do to debug this more given that I don't have any access to the firewall logs and no ability to change the code on the trade server?
Thanks,
Mike
What you describe is common, and it's common to implement a heartbeat to keep TCP sockets alive through such firewalls/gateways like you did.
That hardware might have hard 2160 minutes timeouts (in my experience 20-30 minutes is more common though) , but connections are usually dropped much more aggressively if there's any kind of load. Such firewalls have limited resources, and when they need more connection tracking they tend to drop the oldest connection tracked without any activity regardless of the hard timeout set.
If you want to debug this more, go sniff on the server side of the firewall and see what , if anyting, happens when the server gets a disconnect
I would setup wiresharp on both sides of the firewall to see what happens on TCP (and lower level).
And when the admin says the "timeout for connects" is something. Is that the timeout for an idle, established connection? Anything else does not make any sense I guess.
Also, are you using KeepAlive option for TCP? And is that forwarded by the firewall or not?
As I said, probably want to run wireshark on both sides of the firewall...

Discover computers on local network with specific open port using .NET

I need to "discover" local computers running my windows WCF service, so I can talk to them. Right now you have to enter manually the ipaddress:port combination, but I would like to have a (web?) application that monitors the machines running the service and reports on it.
When I try to connect to an invalid ip/port it takes "forever" to timeout, so it's not feasible to check all the ip on my local network. Is there a quick way to discover which machines have the port open (all of them have the hole in the firewall for that specific port)
TIA
I have done this several time. Just set the timeout value very low.
ALso if its a real machine but without the port open it should fail fast anyway. If you are doing a subnet sweep then, yes, you need to have a (say) 1 second timeout.
Multi-thread the sweep - this is a fun thing to code
edit: I cant find my code. here is link to solution from somebody else
http://social.msdn.microsoft.com/forums/en-US/netfxnetcom/thread/c8161442-61b5-4840-999b-5bb36bda0b6d/
could you have the client configured to contact the web app and report with it's location that it is running your wcf service?
that would require the web app to be running on a known machine that doesnt change.
Why not make them use multicast to broadcast a "HELLO" packet every so often. This is assuming of course that multicast is available in your scenario and your not talking across routing domains. Simply use the "HELLO" packet contents such as ipv4 unicast address to ensure you know what you should be talking to. Of course you don't need to use multicast, you can just send a broadcast to 255.255.255.255 which is not a complex task and then listen for these messages. The benefit of this is that you could also enable negotiation of the port. For instance, if your application generally binds to a port but this port is unavailable, it can automatically choose a port and let you know what port it is bound to. Avoids manual configuration maintenance and headaches involved. Hell, it can even use broadcast to send a message and check if it received it. If it doesn't, fire off an alert letting the systems administrator know.
I use something along these lines for managing test harnesses for soft switches (voice) and it works very well.
Of course, I could be very much off on this. Just thinking out off the box here.

Categories