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
Related
C#/XAML .NET WPF ... Both applications need to have the ability to connect with each other, and both should have listeners. How would I do this as I know that usually a TCP socket is client/server and what I need is basically two servers that act as clients? Is it possible?
First off, I'm sorry there's no code for this answer. I'm not a C# developer (yet). I'm working on a very similar situation and it will be my first foray into the language.
For my scenario I need two copies of the same app to talk to one another but one of them will always start the connection first. It is a very basic game in which two players take turns. I can't hardcode IPs because they need to be able to talk even when not on localhost. My solution is:
One user selects "start game."
App one will open a socket and begin listening. This puts it in the role of server.
App one will then display the IP and Port #.
User two selects "join game"
User two enters the socket info provided.
App two will open a socket for sending, thus becoming the client.
Once the connection is fully established those sockets will be handed off to the code which handles the actual game play. This is possible because game play is identical for both parties regardless of who started.
For your scenario you can skip the displaying of the IP and Port. Both sides will begin listening and begin sending. Once a connection is established they can stop doing what isn't needed. i.e. if one successfully opens a client socket it stops listening as it no longer needs to be in the server role.
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.
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.
I have a C# applications which acts like a client and it can be installed on any system which is directly connected to public internet (through data cards or port forwarding) or they can be behind router also (without port forwarding).
The other application which is developed using java acts like a server application which is on the public internet. Now, my java application wants to push a message to C# application which is behind router. Java application has the clients public and private (192.168.x.x) IP address. Java application is supposed to run 24x7.
So, now there are two options for me:
Whenever c# application starts it will establish a socket connection with java application and this socket connection will remain open till C# application gets closed.
Whenever Java application has something for C# application it will create a socket connection with C# application then it will push the message and then close the connection.
Now, with 1st option there is a problem that there will be lots of unnecessary connection since there can be thousands of client application and it may happen that on some day there will be nothing to push for some clients. and I don't know how to go for 2nd option.
What will be the right way to accomplish this task (option 1 or 2)?
Is UPnP protocol right for 2nd option? What are the open source UPnP libraries which has both the API's (C# and Java). I found one such called ohnet. Will it be a right thing for me? I didn't found a single small example for OhNet to test.
2) is not feasible if you don't have control over network configuration at the client end. It won't in general be possible for the server to make connections to the client if the client is behind any moderately secure firewall / router.
So you will in general have have to go for some variant of 1) where the client creates a connection to the server.
You don't necessarily have to keep the connection open though - it's always possible to get the client to poll the server periodically to check if there are any new updates.
If you want realtime updates to the client from the server then you will still need to keep a connection open. This isn't necessarily a problem if you use Java NIO you should be able to handle tens of thousands of simultaneous incoming connections relatively easily.
Using option 2, will you have to queue messages for your C# client until it connects? That could make your Java application run into out of memory problems if the C# application doesn't connect.
I would definitely use method 2 by adding a static route in the router (port forward). You should - however - ensure that the server behind the router is protected from the rest of your network (DMZ).
UPDATE:
Perhaps I have missed something here (method 1 or 2) :-) - but just to make it absolutely clear: It is always the client that should initiate the connection to the server. And yes, you could allow the client to request the server for updates on a regular basis.
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