A service that makes tcp connections to multiple clients - c#

Most of the examples online are examples of a multithreaded tcp server, whereby the server listens for multiple incoming connections from the client.
What I'm looking for is for the "server", to initiate the connections. If I have 100 devices (all different IP address of course), my server will have to make 100 individual connections to each device and receive data from the devices.
This is how I would make my connection to a device
_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
_socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.NoDelay, true);
_socket.SendTimeout = 2000;
_socket.ReceiveTimeout = 2000;
_socket.Connect(new IPEndPoint(IPAddress, TCPPort));
But I would like to know if there's any component out there, that would fulfill the following
establish as many tcp connections as I want to the devices
receive & send data through the connection
handle tcp timeouts/disconnects/etc & re-establish connection to the IP
If there aren't any of such components, are there any tips as to how I should go about doing it? e.g., 1 connection per thread, or how do I handle if the data is received in multiple packets, etc?
Any insights would be greatly appreciated

There are several existing components out there that you could use to achieve what you want. Checkout http://www.networkcomms.net and http://code.google.com/p/lidgren-network-gen3/.
Having said that people always prefer to add that there is nothing stopping you writing everything from scratch yourself as per the example you give.
Disclaimer: I'm a developer for NetworkComms.Net.

Related

Multible programs/instances using the same UDP Port in C#

I am struggling with a bit of network magic and hoped someone would be able to explain me what is happening.
I am trying to reuse udp ports. So if I have multible programs listening on the same udp port i want both of the applications to receive the data send by a different device.
Using the following code I'am able to achive just that:
IPEndPoint localEndoint = new IPEndPoint(IPAddress.Any, 67); //the local endpoint used to listen to port 67
//Create a new UDP Client and bind it to port 67
DhcpSniffer = new UdpClient();
DhcpSniffer.ExclusiveAddressUse = false; //Allow multible clients to connect to the same socket
DhcpSniffer.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); // Connect even if socket/port is in use
DhcpSniffer.Client.Bind(localEndoint);
DhcpSniffer.Client.ReceiveTimeout = Timeout;
//receive on port 67
dhcpPacket = DhcpSniffer.Receive(ref localEndoint);
Both of my programs can listen to DHCP messages in the network and don't block each other.
Now i want to do the same thing with port 15120 where a RTP video stream is streamed to. However this does not work. I am using the same code but with no success only one application at a time can receive the stream, the other will run in a timeout.
IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, port);
//Create a new UDP Client and bind it to port 15120
udpReceiver = new UdpClient();
udpReceiver.ExclusiveAddressUse = false; //this is an attempt to receive the stream on mutlible instances...this works for DHCP but not for RTP for some reason....
udpReceiver.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); // Connect even if socket/port is in use
udpReceiver.Client.ReceiveTimeout = timeout; //set the sockete timeout
udpReceiver.Client.Bind(RemoteIpEndPoint); //bind to the port from any IP
//receive packets on port 15120
Byte[] receiveBytes = udpReceiver.Receive(ref RemoteIpEndPoint);
I hope somebody is able to shine a light on my confusion
Update:
I found out it works with DHCP because it is send to the broadcast IP (255.255.255.255). Now I need to find out how i can change the Socket behaviour to treat my RTP stream as if it was broadcasted so i can see it in two application at the same time. (Yes I could configure my stream-source to broadcast, but this is not the goal of this).
The goal is to reconfigure the Socket to behave as explained. Not to save the stream on a harddrive or redirect it using the local host.
First, its not possible to have multiple programs listen on the same port (As far as I know it's a big security conflict)
What you can do tough, is use a NetworkManager that listen on you port (Lets call it port 8080) who will then redirect the information to you apps ports (App1 could use port 8081 and App2 use port 8082). Either you write your own, using Flask to listen on 8080 and then rerouting the package to localhost:8081 and localhost:8082 could be a simple and fast solution.
Doing this would help you secure the network and you can redirect to as many ports as you need, pretty much like a docker swarm would balance the incoming network to its cluster.
It is not possible with multible programs to access the data from a unicast UDP package, it works only with multicast, there is no "easy" way around this by reconfiguring the UdpClient

synchronous multiple socket client clarification

I am going to create multiple synchronous clients . I need some explanation about below code.
When i am creating a socket like below and call connect what is happening at network level.
I believe when we create a socket and call connect, a TCP/IP connection a tunnel made between client socket and server socket.
Once this sender(socket) connect with server ,that client & server will have a unique tunnel between them.
if i create another client it will have another unique tunnel between them.
In case if we got an error, that the client is not connected, always we should reconnect using existing socket(sender) then we will access the same data/connection that we had.
And we should not create a new socket then we will have a new tunnel and we will lost the previous connection and data.
Socket sender = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp );
sender.Connect(remoteEndpoint)
Please clarify if i am wrong.
What you call tunnel is really called a connection. Broken connections cannot be revived. Data loss is to be expected.
When you reuse an existing socket object to connect again you are creating a new connection. Reusing socket objects is not recommended (by me) because it is confusing.
Note, that TCP does not know what a socket is. The spec does not contain that word. Sockets are OS-level things.

Discovery in c#

I've to implement some discovery for an internal solution.
We have two kind of software:
Server: They manage a lot of hardware devices and can give access to some data (.Net remoting)
Client: They can display data of one or several Server(graphs, stats, ...)
Currently we are setting the IP by hand on the client.
We would like to implement a discovery.
We have the following requirement:
It has to be usable in c#
When a server is up, it must be displayed as available very fastly
Same when it shut down
If the server doesn't stops in a clean way, we can have a way to detect it(no need to be very fast, can be done every 10-15min).
It can give me some information(Server version, port to use, ...)
We have client computer with multiple network cards, we must discover server on each cards
Do you have a protocol, a library, ... to advice?
We tried UPnP, but seems there is no good Server+client implementation in c# that meet our requirement
Use UDP broadcasts from the discovering app (client):
int broadcastPort = //something
byte[] msg = //something
//Cycle this for all IP adresses
IPAddress broadcastIp = //Broadcast address for this net
IPEndPoint destinationEndpoint = new IPEndPoint(broadcastIp, broadcastPort);
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
sock.SendTo(msg, broadcastEndpoint);
And have the discovered app (Server) answer, to receive the answer use UdpClient.Receive(), which gives you the IP of the answering station.

Uniting TCP and UDP in C#

So ideally, I am looking for a way to unite TCP and UDP on the server and manage both these connections under individual client threads. Currently, I am wondering if it is possible to accept a TCP connection and set up UDP communication from that.
Here is my ideal setup:
Client connects on TCP to server via TCPClient.connect()
Server accepts TCP connection via TCPListener
when server accepts TCP connection, it also gets the IPEndpoint from the TCP connection
and uses that to begin UDP communcation with:
serverUDPSocket.BeginReceiveFrom (byteData, 0, 1024,
SocketFlags.None, ref (Endpoint)ThatIPEndpointThatIJustMentioned,
new AsyncCallback(client.receiveUDP),
(Endpoint)ThatIPEndpointThatIJustMentioned);
^so this is where I am running into a little bit of a theoretical issue. From my understanding, the endpoints for TCP and UDP would be formatted differently. How can I resolve this issue? I would like to avoid having the client connect to UDP on a separate thread and then uniting these threads under a single managing class.
EDIT:
Here is the code that I am trying to implement:
//Listening for TCP
TcpClient newclient = listenTCP.AcceptTcpClient(); //Accept the client
Client clientr = new Client(newclient); //Create a new Client class to manage the connection
clientr.actionThread = new Thread(clientr.action); //This thread manages the data flow from the client via the TCP stream
clientr.actionThread.Start(clientr);
EndPoint endPoint = newclient.Client.RemoteEndPoint; //so this is the sketchy part. I am trying to get the endpoint from the TCP connection to set up a UDP "connection". I am unsure about the compatibility as UDP and TCP sockets are different.
UDPSocket.BeginReceiveFrom(new byte[1024],0,1024, SocketFlags.None,ref endPoint, new AsyncCallback(clientr.receiveUDP), null); //the AsyncCallBack is like the manager thread for UDP (same as in TCP)
clients.Add(clientr);
There is no problem in creating two listeners in one application, even if they use different protocol. I suppose you are not asking if you can do it on the same port (there is no point to do it anyway).
However listener is consuming thread so it need different thread if there is gui or some process to do in application (for example calculations meanwhile).
If you want to do everything in one thread you must first receive message from first listener, then setup second one. There is no possibility to setup 2 listeners in one thread at the same time because if you setup first listener it will consome whole thread waiting for message.
This was due to a lack of understanding of UDP on my part from the code level.
I ended up setting up the other method I described where it would accept initial UDP packets individually and then direct the communication (EndPoint + Message) towards a managing client class by comparing IP addresses.

Server/client sockets

Ok so I am new to socket programing and I'm making a game that is going to run from a server. I am going to try to be able to get a hundred clients to run off my server. Should I make one listener instance or one for every client? Also I've tried to make a hundred listeners all at 100 different ports but when I run my server I get an error while trying to start my listeners. The game is going to be a 3D RPG/MMORPG. Most of the game logic is in the clients though. What do you think that I should do?
If you are going to use TCP sockets, then you should create one listener socket (i.e. create a socket, bind it to a specific port and call Listen() on it). Then, when you Accept a connection and get another socket, which you use for receiving/sending data from/to client:
Socket socketListener;
// create listening socket
socketListener = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
IPEndPoint ipLocal = new IPEndPoint(IPAddress.Any, 30120); // use port 30120
//bind to local IP Address.
socketListener.Bind(ipLocal);
//start listening
socketListener.Listen(4);
while (true) // loop that accepts client connections
{
Socket socketWorker = socketListener.Accept();
HandleClientConnection(socketWorker); // your routine where you communicate with a client
}
Also, consider using sockets in asynchronous mode, that will be more efficient in terms of performance.
You only ever have one listener per server endpoint. The listener will then create a connection for the client that uses a different port. It is this connection you actually use for communication.

Categories