Here is my scenario:
Multiple sockets on one application
I want to receive and send on any number of these sockets
The only solution I have found so far to get around threading issues and bizzare exceptions is:
Each socket has it's own thread
Each socket has it's own concurrent queue which it constantly checks to see if it has a message to send
To send from a specific socket, regardless of thread, then you just add the message to the correct socket concurrent queue
However, this get's pretty costly. I am not a big fan of threading in general, and I have a niggly feeling there's a much better way. I am thinking about the poller - it allows you to receive from multiple sockets without needing to create a new thread per socket (as far as I'm aware). If this is right, is there no way to get it to send pending messages?
Otherwise, is multiple threads my only option? Thanks
Related
I'm creating a network protocol based on Tcp, and i am using berkeley socket via C#.
is the socket buffer gonna mixed up when two threads trying to send data via socket.send method at a time?
should i use lock for accessing one thread at a time?
According to MSDN, the Socket class is thread safe. So, that means you don't need to lock the send method and you can safely send and receive on different threads. But be aware that the order is not guaranteed, so the data won't be mixed if you send it all at a single call to the send method instead of chuncked calls.
In addition to that, I would recommend to lock and flush it just in case you don't want the server swapping the responses across multiple concurrent requests. But that doesn't seems to be this case.
I am using TcpListener (Clase) example https://msdn.microsoft.com/es-es/library/system.net.sockets.tcplistener(v=vs.110).aspx in order to process TCP requests.
But It seems like at the same time this TCP Listener is gonna accept multiple requests that should be processed later in a couple of Web Services together and result must be returned to the TCP client.
I am thinking to do following:
Get a stream object for reading and writing NetworkStream stream = client.GetStream(); and save it in special container class.
Put this class to special Queue helper class like this one C#: Triggering an Event when an object is added to a Queue.
When Queue is changed fire implemented event to process the next queue item asynchronously using Task.
Within a Task communicate with Web Services, and send the response to TCP Client.
Please, let me know this architecture is vital and able to resolve the multiple requests to TCP Listener.
I'd recommend you netmq. Have a look https://github.com/zeromq/netmq
Using queue is definetly viable idea, but consider what purpose it serves. It limits how many requests you can process in parallel. You may need to limit that in several cases, and most usual is if each request processing performs CPU-bound work (heavy computations). Then your ability to process a lot of them in parallel is limited, and you may to use queue approach.
In your request processing performs IO-bound work (waiting of web request to complete). This does not consume much server resources, and you can process a lot of such requests in parallel, so most likely in your case no queue is needed.
Even if you use queue, it's very rarely useful to process just one item at a time. Instead, process queue with X threads (where X again depends on if work is CPU or IO bound, for CPU you might be fine with X = number of cores, with IO you need more). If you use too few threads to process your queue - your clients will wait more for basically nothing, and can even fail by timeout.
I am still learning C# so please be easy on me. I am thinking about my application I am working on and I can't seem to figure out the best approach. This is not a forms application but rather a console. I am listening to a UDP port. I get UDP messages as fast as 10 times per second. I then look for a trigger in the UDP message. I am using an event handler that is raised each time i get a new UDP packet which will then call methods to parse the packet and look for my trigger. So, i have these questions.
With regard to threading, I assume a thread like my thread that listens to the UDP data should be a permanent thread?
Also on threading, when I get my trigger and decide to do something, in this case send a message out, i gather that I should use a thread pool each time I want to perform this task?
On thread pools, I am reading that they are not very high priority, is that true? If the message I need to send out is critical, can i rely on thread pools?
With the event handler which is raised when i get a UDP packet and then calls methods, what is the best way to ensure my methods all complete before the next packet/event is raised? At times I see event queue problems because if any of the methods take a bit longer than they should (for exampe writing to a DB) and the next packet comes in 100ms later, you get event queue growth because you cannot consume events in a timely manner. Is there a good way to address this?
With regard to threading, I assume a thread like my thread that listens to the UDP data should be a permanent thread?
There are no permanent threads. However there should be a thread that is responsible for receiving. Once you start it, let it run until you no longer need to receive any messages.
Also on threading, when I get my trigger and decide to do something, in this case send a message out, i gather that I should use a thread pool each time I want to perform this task?
That depends on how often would you send out messages. If your situation is more like consumer/producer than a separate thread for sending is a good idea. But if you send out a message only rarely, you can use thread pool. I can't define how often rare means in this case, you should watch your app and decide.
On thread pools, I am reading that they are not very high priority, is that true? If the message I need to send out is critical, can i rely on thread pools?
You can, it's more like your message will be delayed because of slow message processing or slow network rather than the thread pool.
With the event handler which is raised when i get a UDP packet and then calls methods, what is the best way to ensure my methods all complete before the next packet/event is raised? At times I see event queue problems because if any of the methods take a bit longer than they should (for exampe writing to a DB) and the next packet comes in 100ms later, you get event queue growth because you cannot consume events in a timely manner. Is there a good way to address this?
Queue is a perfect solution. You can have more queues if some messages are independent of others and their execution won't collide and then execute them in parallel.
I'll adress your points:
your listeting thread must be a 'permanent' thread that gets messages and distribute them.
(2+3) - Look at the TPL libarary you should use it instead of working with threads and thread pools (unless you need some fine control over the operations which, from your question, seems like you dont need) - as MSDN states:
The Task Parallel Library (TPL) is based on the concept of a task, which represents an asynchronous operation. In some ways, a task resembles a thread or ThreadPool work item, but at a higher level of abstraction
Look into using MessageQueues since what you need is a place to receive messages, store them for some time (in memory in your case)and handle them at your own pace.
You could implement this yourself but you'll find it gets complicated quickly,
I recommend looking into NetMQ - it's easy to use, especially for what you describe, and it's in c#.
At the first look when using asynchronous methods on the socket level, there shouldn't be problems with sending and receiving data from the associated network stream, or 'directly' on the socket. But, you already probably know, there is.
The problem is particularly highlighted on the Windows Mobile platform and the Compact Framework.
I use asynchronous methods, BeginReceive and the callback function which performs ends a pending asynchronous read for the received data (EndReceive) from the async. result.
As i need to constantly receive data from the socket, there is a loop which waits for the data.
The problems begins when i want to send data. For that purposes before sending some data through the socket i'm "forcing" ends of asynchronous read with EndReceive. There is a great delay on that (sometimes you just can't wait for this timeout). Timeout is too long, and i need to immediately send the data. How? I don't want to close the socket and reconnect.
I use synchronous method Send for sending data (although the results are the same with async. methods BeginSend/EndSend). When sending is finished, i start to receive data again.
Resources that i know about:
stackoverflow.com...properly-handling-network-timeouts-on-windows-ce - comment about timeouts,
developerfusion.com...socket-programming-in-c-part-2/ - solution for simple client/server using asynchronous methods for receiving and synchronous method Send for sending data.
P.S.:I tried to send the data without ending asynchronous receive but then i got SocketException: A blocking operation is currently executing (ErrorCode: 10036).
Thanks in advance! I hope that i'm not alone in this 'one little problem'.. : )
Have you considered to use Poll (or Select for multiple sockets) static method instead of BeginReceive to check if there are data for read? In my opinion this is causing you the trouble.
In C#, when receiving network data with the BeginReceive/EndReceive methods, is there any reason you shouldn't process the packets as soon as you receive them? Some of the tasks can be decently cpu intensive. I ask because I've seen some implementations that push the packets off into a processing queue and then handle them there. To me this seems redundant because, as far as I know, the async methods also operate on a thread pool.
Generally, you need to receive 'enough' packets to have a data item that is 'processable'.
IMO, It's better to have one thread whose job is receiving data, and another to actually process it.
As Mitch points out, you need to be able to receive enough packets to have a complete message/frame . But there's no reason why you shouldn't start processing that frame immediately and issue another BeginReceive. In fact, if you believe your processing could take some time, you're better off handing it off to the worker thread-pool rather than block a thread from the i/o pool (which is where your callback will fire).
In addition, unless you're expecting a low number of connections, spawning a thread to handle each connection is not a very scalable approach, although it does have the benefit of some simplicity.
I recently wrote an article on pipelining data-processing off a network socket, which you can find here.