I am starting a small file sharing project on a local network. A user must be able to send a sentence (for the moment) to another user of his choice, connected to the same wifi of our house. The problem is that I cannot make a server with several clients, because at any time the server is liable to stop.
For example: imagine that I have three laptops: A, B and C. A is the server and communicates with B and C, and B and C also communicates thanks to A. But I must be able to turn off A but maintain a connection between B and C so they can continue to send sentences to each other.
I have started to create a windows service in C # which will run in the background. But is there any other way than to make A, B and C be both client and server ?
Thanks
As I know there is no limit for a node in network to be a server and at the same time a client.
If that system has IP and a port open, it can act like server. It should only listen on that port for incoming requests. Also at the same time it can connect to another server.
If system B knows about system C's IP and port, they can communicate with each other.
But in real situations like a messaging app, clients should send messages to server cause each time a client connects to a the network, it gets new IP.
So if this is not a problem in your network you can do what you want. But if it is, you can define a simple protocol between clients that at the start of the connection, they exchange their IPs so if the server turned off, they can talk to each other.
Related
I have a C# Console Application where I'm trying to implement TCP Hole Punching.
I need to listen on a Local Port and at the same time (simultaneously/asynchronously) connect to 2 different remote hosts (in reality a remote hosts public and private endpoints) using the same Local Port.
As I understand I somehow need to bind the Sockets/Ports but I can't figure this out in C#.
There's the TCPListener, TCPClient and Socket classes and I don't know which ones to use to accomplish what I need.
I'm following this guide http://www.bford.info/pub/net/p2pnat/index.html Chapter 4.2
From the same local TCP ports that A and B (Clients) used to register with (Server) S, A and B each asynchronously make outgoing connection attempts to the other's public and private endpoints as reported by S, while simultaneously listening for incoming connections on their respective local TCP ports.
I've already implemented the server part using NodeJS and it's working fine, I'm struggling with the Local Port stuff mentioned above.
I'm pretty sure that TCP only allows a 1-2-1 connection between client and server and ports. The only way to setup the multiple connections is to create two different sockets.
The TCP hole punching you're referring too I have tried before. You need to basically use the relay server to tell both A and B how to connect.. So do as follows:
1) Client A connects to Server on one port
2) Server tells Client B your IP and the port (this will be a new connection you will be setting up, different to your connection to the server)
3) Server tells Client A the IP and Port that Client B will be using
4) Client A uses the info provided to create a new connection directly to client B
5) Client B uses its info about your "new" connection to try and accept the incoming request
6) It might fail to handshake a couple of times due to latency, so build in some sort of repeater to keep trying the connection
7) You eventually should have a direct connection to B
I have a situation when I have three computers A, B, C.
Computer A and B are on routable networks and can communicate with each other (different subnets). Computer C is not routable but is on the same subnet as B.
I want to monitor computer C from computer A using SNMP and cacti.
What I'm trying to write is an SNMP "Proxy" to sit on B which listens to a custom port and gets all requests made for SNMP from computer C.
Is this possible?
Thanks for any and all help.
Andrew.
I don't see why you couldn't set up a UdpProxy on B that tunnels SNMP from the manager A to the agent C.
You'd use the .NET UdpClient class http://msdn.microsoft.com/en-us/library/system.net.sockets.udpclient.aspx
I beleive SNMP uses two ports so you'd have to bind a UdpClient to those ports allow for receiving from the manager IP (and agent IP for Traps). Once you receive data you have to resend it to the agent IP and then send the response back to the manager. In the case of Trap messages (alerts/notifications from the agent) you'd have to send them to the manager.
I am developing a LAN-based database application. It involves a central "server" app to house the database, along with many "client" applications that access it.
The "server" will be a simple C#-based HTTP server that responds to GET and POST requests. However, since it is designed to be able to run from any laptop on the network, I am wondering how to establish the connection between clients and the server without knowing the IP address.
I suppose I could ping every IP address from 192.168.0.0 to 192.168.0.255, and then test those that responded to see if any are my server. But I would only do that if there is no better way. Any suggestions?
Many of these types of discovery services run by putting out some kind of beacon on either the subnet broadcast address (for 192.168.0.0/24 it would be 192.168.0.255) or by putting out a beacon on a multicast address.
Multicast is particularly interesting because in a properly configured network, it allows hosts to find the service even across subnets. Routers and switches won't generally forward broadcast packets across subnet boundaries, but multicast packets will.
The beacon would have information in it such as the port the service is running on, what type of service it is, whatever is needed to start using the service.
To head you in the right direction, what you should do is have the database server running on a specified port. Then send out a broadcast to that port from the client (the system needing to connect to the database). When the database server receives this, it will be able to respond to the sender, allowing a handshake to occur.
Of course, you will need to validate the database server's authenticity (to make it secure, unless you aren't worried about that). This can be as simple as having the client display 4 numbers which then need to be typed into the database, so that the database can send the 4 numbers back to the client proving it is the right computer (how the iTunes remote works), or you can use certificates (but that is too complex a topic for me to cover correctly).
After that the two computers will know each others IPs, and you're set!
I have a server application and a client application in order to send and receive files between computers.
you may skip this part:
My algorithm is as follows:
`server: start listening for connections
client: establish a connection with the server
server: start a thread where that thread consist of a method listening for data send through the network stream
client: also start listening for data on a while loop runing on a separate thread.
\\so far if the client sends a byte array through the connection netwrok stream the server will receive it.
\\ also in each while lop the client and server there is a switch statement. if data received commes with the string "<file>" then it will start listening for the transfer of a file
client: send the string "<file>" to the server and start listening for that file on a different method.
server: because it receives the "<file>" keword it exits the listening loop and sends "<ok>" reply
.... so the talking between server and client keeps going ...........`
also the server is running yet more other threads such as still listening for
new connections. maybe another client want's to connect to it. so every time
a client connects the server, the server will start doing the same process
again on a separate thread (listening for new connections).
So as you can see everything that get's sent through the network stream get's received by the other application.
So everything works great when a connection is established
Now think about the things that have to happen in order to establish a connection from computer A that happens to be in a house and Computer B happens to be on a office on a different network. Note (computer A and computer B have internet access). so let's say you want your computer A to be the server and computer B to be the client. So you will have to start the server. great the server is now running. Then you will start the client application. You will also have to tell the router in the house to forward all traffic from port X to that server computer so that computer B is able to find it. Once you do that computer B is able to establish a connection. If next day you have a different IP address because most of us we don't have static IP you will have to change that IP on the client computer in order to establish a connection. so it can get quite complicated and not friendly. Also you may want your office computer to be the server because it might always be on but maybe you don't have access to the router so you are screwed.
Solutions:
1)
on my house call my internet service providers and pay to get a static IP.
I have not developed an algorithm but basically now computer A and computer
B will be clients and they will be connected to my computer at my house.
(on my house I will have to configure the router obviously to do port forwarding).
so know if computer A wants to send a file to computer B the server at my house
needs to have those to connections. the connection between computer A and the
connection through computer B. If something get's sent to the server at my
house from computer A then sent that to computer B and vice versa.
problems with this solution is: The upload speed at my house is very slow therefore
the transferring of files will be slow. also I don't know if my network at my
house will be able to manage multiple connections.
2)
step 1)
Host a website from my home still getting a static ip address. this time I also
have to get a domain so that users can remember me. so let's say that I am able
to host this website hosted on my house as somedomain.com . soon you understand
the purpose of the website....
step 2)
I don't know that much about this it is called "UDP punch hole into firewall".
this basically tells the router to port forward all traffic from port x to the
server so that users don't have to open ports on their routers. I DO NOT KNOW
HOW TO DEVELOP THIS I HAVE JUST HEARD ABOUT IT. so if I develop this computer
A will be able to connect to computer B without having to do any configuration
on the router which is nice.
step 3)
let's say that computer B is the server and computer A is the client that want's
to connect to computer B. so computer B will talk to my website at my house and
tell it that it is listening for connections on the ip address xxx.xxx.xxx.xxx .
then the client computer will access the website at my house and see the ip address
of computer B. now the connection is going to be able to be established.
step 4)
If the internet IP address of computer B changes for example. then let my website
know the new IP address. next time the client want's to connect to the server it
will be able to find the correct IP by looking into my website.
problems with this technique: I do not know how to implement
"UDP punch hole into firewall" so that users do not have to do any configurations
on their routers. an example of this will be helpful.
3)
there are a lot of companies out there that can host you a website. I don't know
about a company that will let me run a c# console application on their server.
Also I don't know if the file transfer of data going from computer A to a server
then to Computer B is more efficient than data going from computer A to computer B.
This solution will enable me to stop thinking about users having to configure their
routers which is nice.
This application enables you to do many more things. I know there are several applications that will enable me to just transfer files. It will be nice if someone will point me on the right direction of which technique to use.
If you use a a free DNS provider like DynDns free and a DNS updater for your dynamic IP like this one, then you can connect to your server by DNS name instead of IP address. Using the updater, when your address changes, the DNS record will be updated at the DNS provider.
Another option might be to use DropBox to synchronize a folder between the client and the server, and then convert your server application into a directory monitor that looks for new files synchronized by dropbox.
I need some feedback with some programming logic.
I'm developing a TCP Server using C#, which will also act as a TCP client. Basically, a client device (A) contacts my TCP Server and sends information. Based on that the TCP server may (or may not) talk to another server (Z) over TCP, send some data to it and sometimes get a response which it passes back to device A. So far so good, this works quite well. However, sometimes Z creates a new connection to my C# TCP server, and wants to send some data to device A.
This is what I am struggling with. I can get the data from Z, read it and see the destination IP address in the text that is read. But how do I send that to device A, which is still connected via a TCPListener on it's own thread?
I could use static variables and the "lock" mechanism to have the thread look for something to send to the device, but what happens if I add device B & C as well?
I basically need some way of, based on the data sent from Z on a new connection, determining which TCPListener on which thread the data should be sent to the devices.
It's doing my head in so any links you may have or rough logic (doesn't have to be code) would greatly help.
And yes, I've been searching Google for a while, but all the examples I have found are simpler than what I need to do.
Thanks in advance!
you can keep a Dictionary<IPAddress,TCPClient> for this purpose and send the message to the destination IP. Make sure you handle the multiple clients from the single IP gracefully either by droping the previous connection while accepting new one or instead having Dictionary<IPAddress,List<TCPClient>>