What is the preferred way to handle this TCP connection in C#? - c#

I have a server application (singleton, simple .NET console application) that talks to a GlobalCache GC-100-12 for the purpose of routing IR commands. Various .NET WinForm clients on the local network connect to my server application and send ASCII commands to it. The server application queues these ASCII commands and then sends them to the GC-100-12 via a TCP connection.
My question is, what is the best way to handle this connection from the server's point of view? I can think of two ways:
Create and Open a new TcpClient for each individual request. Close the TcpClient when the request is done.
Create and Open one TcpClient when the server starts and use a keep-alive (if necessary) to keep the connection open for the lifetime of the server object.
I ask this question because I wonder about the overhead of creating a new TcpClient for each request. Is it an expensive operation? Is this a bad practice?
Currently I am doing #1, and printing the results of each transmission to the console. Occasionally some connections timeout and the command doesn't get routed, and I was wondering if that was because of the overhead of creating a new TcpConnection each time, or if it is due to something else.
I can see #2 being more complicated because if the connection does drop it has to be recreated, and that will require a bit more code to handle that circumstance.
I'm looking for any general advice on this. I don't have a lot of experience working with the TcpClient class.

We had a simillar case of opening a telnet session to an old PICK based system. We found that the cost of opening the TCP connection each time a request came in was fairly expensive, and we decided to implement a no-op routine to keep the connection open. It is more complex, but as long as your end point is not trying to serve many many clients then pinning a connection sounds like a viable solution.
You could also set it up to have a timeout, if you want to prevent keeping a connection open when there is no traffic. Five minutes of no activity then shut down the connection.

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.

C# Check a port for incomming traffic

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.

Scalability test - Connections dropped after many connections are established

I am programming with sockets (TcpListener and TcpClient actually) in C#. I wrote a server that accepts client connections and streams data to them.
In order to test scalability, I wrote a test harness that creates a certain number of connections (say 1000) in a loop, connects to the server, and writes whatever data is received to the console.
After the server receives about 1300 connections, the clients' connection attempts start failing with a regular "No connection could be made because the target machine actively refused it" exception. If the clients keep trying, some connections get through, but there are still many of them that don't. I even tried putting in delays, e.g. three simultaneous clients each opening one connection per second to the server, but the problem remains.
My guess was that the listen backlog was becoming full, but given the delays I introduced, I now doubt it. How can this behaviour be explained and solved?
Edit: before anyone else jumps on this question and marks it as duplicate without having read it...
I am using asynchronous sockets using the Asynchronous Programming Model. That's the old BeginXXX/EndXXX pattern, not the new async/await pattern. The APM uses the Thread Pool underneath, so this is not a naive one-thread-per-connection model. The connections are dormant most of the time unless I/O occurs. In that case, the .NET Framework automatically allocates threads to handle this.
Edit 2: The gist of this question, for those who thought it was too [insert silly adjective here], is: why does a server drop connections when under a heavy load? The error message I quoted usually occurs when a connection cannot be established (i.e. when you got the ip/port wrong), but this clearly isn't the case.

How to maintain a connection when the client is not opened and the server is?

I have a Client & Server c# program.
The Client ( the one who's receiving connections).
The server ( is the one who's connecting to the client ).
When the server is opened the customer(server)with his email and address appears in the Client window.
BUT when the client is closed and reopened then connection is loosed and the customer needs to close the server and open it again.
How can I maintain the connection without telling the customer to close and reopen the server?
I'm using TCP Connection and scokets.
A solution for this might be using lazy connection initialization with error handling for cases when the "client" is not online.
You can create a wrapper for your connection, which handles the initialization, can check current connection state and wrap all your actions with error handling in case the connection could not be initialized.
WCF is a good abstraction layer for this, but might be too heavyweight and has quite steep learning curve, especially its setup/config part in your project.
Also, as was already mentioned, it is part of the client/server design that usually the client initializes the communication with some sort of login/subscription message, not the other way around - that would solve your problem here as well.

Are TCP Connections resource intensive?

I have a TCP server that gets data from one (and only one) client. When this client sends the data, it makes a connection to my server, sends one (logical) message and then does not send any more on that connection.
It will then make another connection to send the next message.
I have a co-worker who says that this is very bad from a resources point of view. He says that making a connection is resource intensive and takes a while. He says that I need to get this client to make a connection and then just keep using it for as long as we need to communicate (or until there is an error).
One benefit of using separate connections is that I can probably multi-thread them and get more throughput on the line. I mentioned this to my co-worker and he told me that having lots of sockets open will kill the server.
Is this true? Or can I just allow it to make a separate connection for each logical message that needs to be sent. (Note that by logical message I mean an xml file that is of variable length.)
It depends entirely on the number of connections that you are intending to open and close and the rate at which you intend to open them.
Unless you go out of your way to avoid the TIME_WAIT state by aborting the connections rather than closing them gracefully you will accumulate sockets in TIME_WAIT state on either the client or the server. With a single client it doesn't actually matter where these accumulate as the issue will be the same. If the rate at which you use your connections is faster than the rate at which your TIME_WAIT connections close then you will eventually get to a point where you cannot open any new connections because you have no ephemeral ports left as all of them are in use with sockets that are in TIME_WAIT.
I write about this in much more detail here: http://www.serverframework.com/asynchronousevents/2011/01/time-wait-and-its-design-implications-for-protocols-and-scalable-servers.html
In general I would suggest that you keep a single connection and simply reopen it if it gets reset. The logic may appear to be a little more complex but the system will scale far better; you may only have one client now and the rate of connections may be such that you do not expect to suffer from TIME_WAIT issues but these facts may not stay the same for the life of your system...
The initiation sequence of a TCP connection is a very simple 3 way handshake which has very low overhead. No need to maintain a constant connection.
Also having many TCP connections won't kill your server so fast. modern hardware and operating systems can handle hundreds of concurrect TCP connections, unless you are afraid of Denial of service attacks which are out of the scope of this question obviously.
If your server has only a single client, I can't imagine in practice there'd be any issues with opening a new TCP socket per message. Sounds like your co-worker likes to prematurely optimize.
However, if you're flooding the server with messages, it may become an issue. But still, with a single client, I wouldn't worry about it.
Just make sure you close the socket when you're done with it. No need to be rude to the server :)
In addition to what everyone said, consider UDP. It's perfect for small messages where no response is expected, and on a local network (as opposed to Internet) it's practically reliable.
From the servers perspective, it not a problem to have a very large number of connections open.
How many socket connections can a web server handle?
From the clients perspective, if measuring shows you need to avoid the time initiate connections and you want parallelism, you could create a connection pool. Multiple threads can re-use each of the connections and release them back into the pool when they're done. That does raise the complexity level so once again, make sure you need it. You could also have logic to shrink and grow the pool based on activity - it would be ashame to hold connections open to the server over night while the app is just sitting their idle.

Categories

Resources