C# Check a port for incomming traffic - c#

I have a server that i use to run game servers on for my friends and me, and some of the servers are "attack-able" (monsters can destroy our base) so i want the server to be shut down when not in use. Then i was wondering if there was a way to detect if there was an incoming signal (trying to connect to the server) on the given port, so the server can be turned on?
Raw question:
Is there a way to detect, if someone is trying to send a message (or connect) through a specific port in c# (or another language better suited for this action)?

Yes, you have to create a server to listen on that port. The problem you will face is that the server you create to detect incoming connections will need to be shut down so the game server can be turned on. They can't listen on the same port unless they're coded to work together and that likely isn't going to be the case with your game server.

If you want to see if there is any connections in use you can try to list all current TCP connections (assuming server using TCP) and find if there is any alive connection to specific port.
Resmon does this in his "Network" tab, so there must be a way to access it programmatically.
Here is answer describing how to get active TCP connections.
How can I get all the the active TCP connections using .NET Framework (no unmanaged PE import!)?
You probably should monitor server with some intervals because player might lose and reestablish connection, so sample it every 10 seconds or so and if there is no connection for more than few samples - shut down the server.

Related

Client usually disconnected from server after a few dozen minutes

I've created a server-client communicate program in .NET (c# or vb.net) using TCPListener - Socket on port 8080. In simple words, the program work like a chat software, client connect to server, and both wait for message from each other and then process it.
To retrieve packet from client, i using are using a "While" method like this :
While true
Dim Buffer(4096) As Byte
s.Receive(Buffer)
Dim strDataReceived As String = System.Text.Encoding.ASCII.GetString(Buffer)
ProcessData(strDataReceived) 'Process data received...........
End while
When testing both server.exe-client.exe in local, the software work fine for several hours without any problem.
But when i start to run the server.exe in my real server, the connection between server-client usually become lost each other when client connected after a few dozen minutes. The symptom is client send packet to server but server does not receive the packet from client when server is still standing in 'sck.receive(Buffer)' command. I have tested many times but i still have no lucky to keep the connection run over 1 hour.
I have investigated about this problem but it still very strange :
The server did not installed any firewall software.
The client did not using any proxy and antivirus, firewall software
I using a bandwidth logging software on server to make sure the internet in my server is stable.
I make a 'ping -t' from my client computer to the server and keep looking on it to sure there are no connection lost between client and server . The ping command indicate that the ping time is usually range from 5ms to 50ms and no connection time out occur.
Even I try to unplug the network cable in the client computer for a few seconds, and then replug again to simulation the disconnect event. I've awesome that my connection between server-client is still maintain and it's not the problem that cause my symptom.
I was thinking to write a code for auto reconnect if received timeout. But it could make my software usually delay when reconnecting if the above symptom still there. I really want to know what wrong with my code and which is the solution for me to fix the above symptom?
Likely the server is behind some sort of firewall (Cisco ASA, etc.) which has idle connection timeouts. When you "punch" through a firewall / NAT device, a "session" is created within the firewall kernel. There is an associated resource that has to be reclaimed, so firewalls do not usually allow unlimited connection timeout, but firewalls do support things like dead connection detection.
Adding a keepalive packet / activity every 5 minutes, or disconnecting / reconnecting is the only way around that. Few network admins are going to change their configs to accomodate this. It is pretty simple to implement a "ping" or "keepalive" command in custom TCP application protocols. Just send the string and consume it, you don't even have to respond to the packet to accomplish resetting the idle timer within the firewall, though that would probably be best practice.
When I say keepalive, I don't mean the TCP keepalive socket option. That is a zero-length packet, and is detectable by a good firewall, like Cisco. Cisco admins can setup rules to quietly deny your keepalive packet, so the solution is to implement it above the TCP layer, in the Application layer, by sending a small string of data like "KEEPALIVE\r\n".

Initiating tcp connection from public IP to private machine on another network

I'm having difficulty finding help resources on this. I know how to use the TCPClient class to create a connection between one IP/Port/machine and another.
My doubt is how does that work when one machine wants to initiate a TCP connection to another machine where the destination machine is inside a different network. So the destination network may have hundreds of computers each with its own private ip and the network would have one public IP address. This would be using the TCPClient class or any other that is more appropriate.
I know we could use ports and then inside the network the port could be forwarded to the correct machine but I was looking for a solution like the one services like LogMeIn use. Basically I wanted to use port 80 always and then initiate the connection from the server to that particular machine or others on the same network when I needed.
I suppose, theoretically, I could create the connection first from inside that network, then on the server, save the details and close the connection and then in the near future, when I needed, I would re-open the connection.
So in my scenario, I would have many clients across multiple networks, each network might have multiple internal machines with a client installed. Then on the server I would initiate connection to these machines when needed. Within each network I would want to use port 80 for obvious reasons. The reason I want to initiate the connection from the server and not the client machines is simply to save resources, I couldn't cope with having opened connections until eventually I might need to communicate wit them.
Also, I have no control on the client networks besides them having my client installed.
Ideally, I wish to have c# info, possibly code and not network configuration.
I had this requirement at a previous company. We installed our client/server software (C# based) on numerous different networks with a mix of public/private IPs. I found two relatively simple ways to solve it. First, I want to say that without a public IP, its impossible to connect reliably (in my experience).
When I proposed the solution, I explained the problem to other developers/managers this way.
Your server, the machine with the public IP address [public to clients, but may still be an "internal address"], is like a house without any long distance calling. It can receive calls, but it can't make any calls. The clients are like houses with long distance service. Clients must call the server, because they have long distance. Once connected, any party can talk on the line.
From here you have two choices.
Client connects and never disconnects (this is what I implemented). On the server, I had an object that mapped the client object to the client connection so I could communicate any time with a client that was connected.
Server holds a queue of messages for the client. The client automatically connects on a fixed interval to see if there are any messages (maybe 5 minutes). There would be an option from the server to stay connected for a specific interval. Another vendor called this "fast talk".
There's a couple of approaches.
You could setup NAT - probably no good for your scenario.
You could make an outbound connection from your client.
You could "combine the above" by using STUN (see http://en.wikipedia.org/wiki/STUN) this is quite popular in VOIP for peer to peer scenarios.
The Windows Azure servicebus may have a solution for your problem; NetTcpRelayBinding in hybrid mode allows two comuters behind NAT to create a direct connection with each other. This might not solve your problem if you are money constrained as each connection has an associated cost.The simplest solution is probably to have the clients polling your server.
You may use SignalR, which has been developed for this kind of scenarios.
You must have a third party, though (a server which broadcasts messages from sender to other peers).
But the beauty of this technology is that it chooses the most appropriate way to push data to clients: Polling, long connections, sockets... etc.
This provides an abstraction layer which is quite comfortable.
It has been designed to interact with javascript clients, but may be used in full-C# clients as well.
You need a third server that acts as proxy between your machine and target machine that is behind a firewall.
That is how applications like LogMeIn work.
You can do this using SSH tunnels.
Please check https://serverfault.com/questions/285616/how-to-allow-remote-connections-from-non-localhost-clients-with-ssh-remote-port
The topic is about NAT traversal.
STUN is good choice to try to communicate with client behind NAT.
But if STUN don't work,you can use RELAY service to help to pass the message between your server and remote client.RELAY service is a public service that everyone can reach it.

C# Chat - TCP P2P

I am working on a Peer-to-Peer chat program but have ran across an issue: Running the client and server simultaneously. I do not want a dedicated server to manage connections. I believe the solution may be asynchronous direct connections, but I am not sure.
What I am trying to accomplish is to be able to run the program between two hosts, the program will be started and begin trying to connect to an ip address specified by a text box. At the same time, it will also start listening for incoming connections on the localhost ip address.
***I am using tcp, because on the off chance something is corrupted the message will not be able to be read (it is encrypted)
Issues:
1) It is conceivable a client could be waiting for a period of time before the other program tries to connect. So should some form of a loop must be utilized? If so, how?
2) I assume I need to use multi-threading, with one thread for the server part and one thread for the client part, but an issue is keeping them from hanging. Since both programs are identical there way be a way to listen and simultaneously attempt to connect to the other host.
3) I am also having trouble with making my server listen for connections to it, and do not know how to automatically have it pull the ip address from my computer.
Thanks for any help.
EDIT: This is on a LAN only.
Everything you need to know is in Microsoft's docs.
http://msdn.microsoft.com/en-us/library/w89fhyex.aspx

Is it possible to 'relay' a socket?

I was wondering it it was possible to relay a socket object in either C# or Java? (Preferably C#)
I have lots of little programs i make and host them on my home pc, but my pc is behind a router, so i have to forward a port on my router every time i want to make a new application. So is there a way to send a tcp connection to another application on the same computer? for instance i get a connection in with the first line of text being RELAY::21005 which would then forward that port to localhost:21005 ?
Any help, tutorials, code snippets would be much appreciated. Thank you! :)
One problem you might face with your suggested solution (first line identifies target port) is that you'll have to change all of your client programs to send that first line. That's easy for programs you've written yourself but not so convenient if you want to connect to your PC's web server or ssh daemon etc. It's not impossible of course, but does make it hard.
I'd suggest your routing server listens on two ports - a control port and a "normal" port (I can't think of a better name at the moment). You would send control messages to the control port to indicate "until further notice redirect all incoming connections on the normal port to port nnnn". That avoids having to manipulate client protocols.
I don't know enough C# to provide advice about a C# solution, but in Java I'd simply do something like:
while (true) {
acceptConnectionOnNormalPort()
connectToTargetPort()
startThreadCopyingDataFromAcceptedPortToTargetPort()
startThreadCopyingDataFromTargetPortToAcceptedPort()
}
You'd not be able to scale that easily into thousands of connections...
K I take back my comment, check this out:
http://msdn.microsoft.com/en-us/library/aa395195.aspx
Using this requires the port sharing service to be up (it is disabled by default):
The Net.TCP Port Sharing Service is available on all operating systems
that support .NET Framework 3.0, but the service is not enabled by
default.
All of this is only useful to you if you are using WCF services tho.
The easiest approach IMO is to use ssh tunneling. As I wrote in my comment, there are lots of questions on SU that will show you how to do this.
But assuming that you want to program something ...
You'll need to create a client and a server. The client will have threads that call accept on whatever local ports you want to open. When a connection comes to a port, you create another thread that opens a connection to the server and continually sends data over the wire.
The server program listens on a single port, which you open in your firewall. It waits for connections on that port, and when it receives one it opens a connection to the specified local port. Then it shuffles bytes from one to the other.
The only trick is that you have to define a protocol for specifying the destination port in the client-server stream. Simplest approach is to write a two-byte integer at the start of the stream.
Yes, it is possible to relay a socket.
You can use TURN http://en.wikipedia.org/wiki/Traversal_Using_Relay_NAT
Some of TURN library/application:
pjnath
turnserver.sourceforge.net

C# Changing incoming and outgoing TCP Communication

What is the best way of reading, changing, and resending tcp communications?
For instance i have a server application that tells a master server it's alive sending a packet over TCP on port 3209. It sends out "I'm alive, my ip is xxx.xxx.xxx.xxx and I have currently 3 clients connected to me." the master server then responds, "Hello xxx.xxx.xxx.xxx i see you there."
Whats the best way of MITM of the server sending its packet to the master server? I would like to be able to change "i'm alive," to something like, "I'm changed," or even "currently 3 clients connected" to "currently 0 clients connected"
Any ideas appreciated, thank you.
There's no need to send out that kind of message.
First of all, TCP is connection oriented, so as long as you have a connection you'll be alive.
You can check if you're still connected by using the TCPClient.Connected property.
Secondly, TCP runs over IP so in the IP header you can find the sender IP (is in the socket properties) so no need to send the IP neither.
You can check the remote IP address by using TCPClient.Socket.RemoteEndPoint property.
Finally, the only thing you might be interested in telling is the "3 clients connected part" wich can be coded as a simple integer transmision. That is, a 4 bytes hearbeat.
Getting in the middle of the connection IS tricky and has nothing to do with communication protocols. And honestly it's a hell of a job, if there's a connection already present you'll have to find a way to make the client or the server drop it and then have the server reestablish it to your MIDM. More though, if the connection is made directly to an IP address you'll have to mess with the router tables somehow for the attact to be succesful, if it's not maybe DNS poisoning will work for you... anyway not an easy task.
Those are only ideas... it depends on the class of network, if you have physical access or not, if the client and the server trust each other (as in if they are your applications) and so on... I assume all this is ethical or educational at least... :)
Have a look at SharpPcap or any other packet capturing/injecting library.
In order to MITM, you'll have to force the client to think you're the server and the server to think you're the client. For that, you'll have to send ICMP packet to both machines as described here. Then, you will capture the packets, modify them and inject them to the network (with the correct MAC address).
Pick a different tool - this is too low level a kind of thing to attempt in C#. This kind of thing is achieved (on Vista and later) using the Windows Filtering Platform

Categories

Resources