When to use different ports for client-server application? - c#

When will I normally need different ports for client-server communication?
(This question is for C# and general socket programming).
I have implemented and been using a simple C# client-server application. Basically:
server listens for client
on accepted/connected
server spawn client thread -
server waits for client to talk
client talk
server respond
client talk
server respond etc.
if client stops talking, then server blocks in NetworkStream.Read() mode forever in that spawned thread unless client-side disconnects.
I am now thinking of the situation where both sides keeps quiet until some event happen on either side then only will the client or server sends data across. As such both needs to be in NetworkStream.Read mode concurrently somehow and also be able to send to each other at the same time (if the event happens on both sides simultaneously).
Do we need different ports in this case or can both client and server be in NetworkStream.BeginRead mode without risking a problem with NetworkStream being in both writing and sending mode at the same time?
Thanks.

Excellent question. I have written more than one app with that architecture. When you need to have bi-directional communication, you need two connections (of course, in two different ports) between client and server:
Connection where requests flow from client to server
Connection where requests flow from server to client
That way, both sides will have a NetworkStream ready to be read. And you notice the level of independence between the two flows, allowing you more control over your bi-directional request handling code.

Related

How to manage large number of TCP connections using ASP.NET and C#

I have an application which connects to a third party server let’s call it Server-A. I have been given four different ports i.e.
4000, 40001, 40002, 40003. On each port I can create 20 connections so I can create 80 total connections with server-A. I want to create a service layer that should communicate with server-A on mentioned ports. The technology will be asp.net C#.
The problem statement
1- Application should be non-blocking/asynchronous to entertain 10 to 20 million request per day
2- Whenever the service layer starts it create 20 connections on each port. (Total 80 connections)
2- All connections should remain connected/alive 24/7 and reconnect whenever any connections drops/disconnects. It will send a heartbeat message in idle time.
My Questions
How can I manage these connection? Should I add those to a static list one by one when a TCP socket is successful?
How can I know that a certain connection is dropped/disconnected?
How can I send certain requests on different ports? Let’s say if a>b send it on port 4000 else if a<=b send it on 4001
How can I make it asynchronous?
For an initial start I created a single TCP connection on single port and it works as expected. Then I replicated the same code for other port, but I know it is very bad approach and I have to copy same code 80 times to make 80 connections. I want a clean and scalable way to achieve it, so that in future may be I increase the connection to 100 or more.
Is there any framework which I can use?
Any help would be greatly appraised.
#Kartoos Khan, i have made some services with those requirements and using asynchronous methods is the best way to create high performance services in C#, because:
It does not block IO peripherals, as can be sockets.
Minimize the threads and improve the performance to it.
Let me recommend you the book Writing High-Performance .NET Code. The chapter 4, Asynchronous Programming has the information that you need to know to improve the performance.
In my experience those are my recommendations:
Create a main threat to handle the main program.
Create a class to handle the Socket Server, which implements an asynchronous process to accept connections, using the methods BeginAccept and EndAccept, here is a sample of how to use it.
Create another class to handled the socket connections, which has as a property the Socket object.
2.1 create a method to start the Reading process, which will be called by the Server class to start the communication between the endpoints. This methos will start the process of read in an asynchronous way.
2.2 To read and write in an asyncrhonous way, it is necessary to get the NetworkStream from the socket, and use the methods BeginRead and EndRead, to receive data, and BegineWrite and EndWrite to send data. Here there is the documentation.
In the case that your service only needs to connect to a Server, ignore the step 1and implement the Client class to start the connection to an specific EndPoint.
Use a collection class, as can be a Dictionary, Key-Value-Pair collection, to store each Client Class and use the socket ID as the key to access to each Client Class.
Due each Client Socket handles it own socket, i use to implements a way to reconnect at the same Client Socket, i this way each Client is responsable for itself.
The main program will be responsable to create each Client Server and set the EndPoint of each client, as you need, and start to connect each of them. In this case, TCPClient allow you begin an asynchronous process for connect, using the methods BeginConnect and EndConnect.
Here you can see more details about this issue.
I hope this might be useful for you.
To handle such a large volume of traffic you need to do a few things.
Assumptions
You are connecting to another client’s server.
You have a large volume of web traffic from either multiple machines or from multiple working processes on any given machine.
You know how to create TCP client server objects and handle the connections.
For less than 80 worker threads across your servers:
Because each thread processes synchronously, you only need to use a single connection for each thread.
If no single web server is running more than 20 worker processes, then you can designate a single port for each server to use. Stick the port in your web.config file as a variable and use that when creating connections. You will never hit the limit.
Store your connection in a shared object that the entire app can use (could put this in your BLL layer) and if you have a connection error, re-create a new connection on that thread.
For more than 80 worker threads across your servers:
Do the same as the last step but at this point you either need to negotiate for more connections or you will add a new layer in between your application and the server you wish to reach.
This second layer acts as a broker for the two sides and can manage a pool of connections instead and draws off a connection each time you need to access Server-A and puts it back into the pool when finished.
Anytime you connect to the broker application, spawn a new thread to do the processing until the connection is dropped or closed.
Keep track of your open connections and viola you can have as many clients as you need but your bottleneck will be those 80 connections out even if you have hundreds or thousands in.

Client Server Relationship Confusion

I have 5 computers that control different hardware. One of the five is the main controller for the other 4. I need to send commands from the main controller to the 4 slave controllers over TCPIP. I have very limited experience with Socket programming.
In the system I have which would be the client and which would be the server? It would seem to me that in the configuration I have the line between server and client may be skewed. Both sides need to send and receive commands, is there really a separation of client and server or is that just the convention? Can I have both endpoints as a client and server at the same time using the same socket? Essentially can I have both ends listening and sending requests?
I'm referencing the example code on MSN.
Asynchronous Server Socket
Asynchronous Client Socket
As far as socket connections go, who is the client and who is the server is just a matter of who accepts connections (the server) and who initiates a connect request (the client).
Once the connection is established, traffic can go in either direction (both client and server can send and/or receive data).
Your main controller is the Server. When it comes online it listens for your slaves to announce that they are online. They do this by connecting to the Server as Clients. The Server will Accept the connections.
If each slave performs some special function then you should have a message that the client can send to the server that indicates this function. If all of the slaves are required for the system to function properly then you will need to wait for all of the slaves to announce their distinct functions.
Your Server would then be able to send messages to a distinct Client or broadcast to all Clients. Each Client would only be able to send messages to the Server. If client-to-client communication is necessary you would probably implement message forwarding in the Server. This way, your Clients do not need to know the addresses of the other clients. They would only need to know their function, which would be used to route the messages to the appropriate Client.
I'm basically saying that you need to define a protocol by which your nodes will to communicate. This protocol will dictate which one of the nodes will be the Server and which of the nodes will be the Clients.
If your protocol turns out to be more appropriate for peer-to-peer instead of client-server you might want to consider using UDP instead of TCP.

c# and networking - Client listening and server send and most efficient C# socket networking?

I'm working on a game that depends on the standard System.Net.Sockets library for networking. What's the most efficient and standardized "system" I should use? Should the client send data requests every set amount of seconds, when a certain event happens? My other question, is a port forward required for a client to listen and receive data? How is this done, is there another socket created specifically for listening only on the client? How can I send messages and listen on the same socket on the client? I'm having a difficult time grasping the concept of networking, I started messing with it two days ago.
Should the client send data requests every set amount of seconds, when a certain event happens?
No. Send your message as soon as you can. The socket stack has algorithms that determine when data is actually sent. For instance the Nagle algorithm.
However, if you send a LOT of messages it can be beneficial to enqueue everything in the same socket method call. However, you need to send several thousand of messages per client and second for that to give you any benefit.
My other question, is a port forward required for a client to listen and receive data?
No. Once a socket connection have been established it's bidirectional. i.e. both end points and send and receive information without screwing something up for the other end point.
But to achieve that you typically have to use asynchronous operations so that you can keep receiving all the time.
How is this done, is there another socket created specifically for listening only on the client?
The server has a dedicated socket (a listener) which only purpose is to accept client sockets. When the listener have accepted a new connection from a remote end point you get a new socket object which represents the connection to the newly connected endpoint.
How can I send messages and listen on the same socket on the client?
The easiest way is to use asynchronous receives and blocking sends.
If you do not want to take care of everything by yourself, you can try my Apache licensed library http://sharpmessaging.net.
Creating a stable, high quality server will require you to have a wealth of knowledge on networking and managing your objects.
I highly recommend you start with something smaller before attempting to create your own server from scratch, or at the very least play around with a server for a different game that's already made, attempt to improve upon it or add new features.
That being said, there are a few ways you can setup the server, if you plan on having more than a couple of clients you don't generally want them to all send data whenever they feel like it as this can bog down the server, you want to structure it in such a way that the client sends as little data as possible on a scheduled basis and the server can request more when its ready. How that's setup and structured is up to you.
A server generally has to have a port forwarded on the router in order for requests to make it to the server from the internet, and here is why. When your computer makes a connection to a website (stackoverflow for example) it sends out a request on a random port, the router remembers the port that you sent out on and remembers who sent it (you), when the server sends the information you requested back the router knows you wanted that data and sends it back to you, in the case of RUNNING a server there is no outbound request to a client (Jack for example), so the router doesnt know where jacks request is supposed to go. By adding a port forwarding rule in the router your saying that all information passed to port 25565 (for example) is supposed to go to your server.
Clients generally do not need to forward ports because they are only making outbound requests and receiving data.
Server Starts, server starts listening on port 25565
Client starts, client connects to server on port 25565 and initiates a connection
Server responds to client on whatever port the client used to connect (this is done behind the scenes in sockets)
Communication continues from here.

Communication between C# clients which are behind router and Java server which is on public internet

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.

Does TCP have to be used in a one to one send/receive fashion?

I'm developing an embedded system that connects to a PC over ethernet using TCP sockets. The PC will be the TCP client, and the embedded system the server. If I understand it correctly, the classical communication model is that the client sends some data to the server, and the server responds every time. The server never initiates communication.
What I'd like to do is send commands from the PC to the embedded system, without corresponding responses. The embedded system will then execute the tasks described by the commands. If the embedded system has an error, or has some status message to report back, it will send these back, without being polled by the PC.
I've figured out everything but the receiving on the PC side. I'm programming the PC app in C#.net Can I set up a callback that fires whenever data has been received on the socket? Every example I've seen uses the receive method in a blocking fashion.
You can use asynchronous I/O on the socket stream. This is almost exactly what you're asking for - you start a receive operation and give it a callback to call when the receive is complete.
Check out the BeginReceive/EndReceive functions.
More info here: http://msdn.microsoft.com/en-us/library/bbx2eya8.aspx
The long and short of this is yes, of course.
What you want to do is fire up a new thread for each client that connects that then raises events on an event/command thread. You're under no obligation to respond to a request other than (and this is handled by your operating system's TCP/IP stack) sending ACK when you receive a packet (don't worry about this part the OS does this for you and it's part of what makes TCP/IP reliable).
As long as the socket is active you should be able to send back responses to the client, so basically you need to keep the socket active for as long as any command is running.
Here's a list of examples from Microsoft that should show you how to do this. http://msdn.microsoft.com/en-us/library/bew39x2a.aspx#Y0

Categories

Resources