Q:

Business logic in IO completion Port

I have some doubts in regards of IO Completion Port as well as AcceptEx in winsock2
Please correct me if i am wrong.

AcceptEx is an overlapped way of accepting requests or connection. However, as pointed out by multiple posts on this site that AcceptEx is prone to DOS attack if AcceptEx is expecting data but is not sent by the connected client. So, can it be solved by just putting 0 to the dwReceiveDataLength?
Besides, what is the advantages to be able to receive data from client when accepting the respective connection rather than receive the data later using AcceptEx?
After accepting connections from opposite endpoint and associates it with IO completion port, the requests are queued in IO completion port as completion packets which are associated with their respective handle. The worker threads that block on the completion port would be woken up depending on the NumberOfConcurrentThreads to serve the requests. So, is the threads in the completion port the IO threads?
So, where should I implement business logic or operation in the socket server? For example, a request from client that send numbers to the server for processing while the server act like a calculator that responds by echoing back the calculated output. Thus, can this logic be implemented in IO Completion Port?
If the logic is implemented in IO completion port (When IO threads (assumed) that are active in IO completion port are performing WSARecv or WSASend)), would the IO threads block while waiting for the calculation to finish thus making no connection is able to be accepted if the backlog are all taken?

EDITED:

For example, after accepting the client socket and queued/ associated in the IO completion port(main_cpl_port), threads that block on this main_cpl_port call GetQueuedCompletionStatus to dequeue completion packet and subsequently read data into allocated buffer. Before any response is written back to the client, the buffer is processed/ parsed for "command" (eg: GoToCalculator, GoToRecorder).
For example, GoToCalculator is responsible for other calculation related commands.
In this case, GoToCalculator is actually another IO completion port that caters all those requests related to calculation. Let say the completion port is named as calc_completion_port.
Thus, is it possible that the completion packet from main_cpl_port to be posted to calc_completion_port for future IO (send and recv) from the client socket which is currently associated with main_cpl_port. Is this what PostQueuedCompletionStatus is used for?
Is message sent from client after posted to calc_completion_port can be received by threads that block on this completion port?
In other words, how can I redirect the connection to other completion port from another? 

A:

1) Avoiding the potential AcceptEx DOS attack is easy, just don't provide any space for data and the AcceptEx will complete as soon as the connection is established.
2) Using AcceptEx means that you don't need to have a separate thread to run an accept loop. This removes one thread from your system and reduces context switching. This is especially useful if you are listening on multiple sockets (different ports/interfaces) as each listening socket would need its own accept thread.
3) Yes, the worker threads that call GetQueuedCompletionStatus on an IOCP can be thought of as I/O threads...
4) It depends. I've built systems with distinct, fixed sized pools of I/O threads which never do any blocking operations and separate expanding thread pools designed to perform blocking operations. The idea being that this would prevent all of the threads being blocked and preventing I/O... This requires that you pass work items off to the other thread pool and it causes unnecessary context switching and complexity but it means that you always have threads to do I/O operations (such as handle new connections as AcceptEx completes)... This kind of design used to work well back when the IOCP APIs used to cancel pending operations if the thread that issued then exited before the operation completed. Now that the OS has changed the rules and pending operations are not cancelled there's no real reason why you don't just have an expanding/contracting pool of I/O threads and do all your work there... You just need to track how many threads are available and create/destroy threads as you need to expand/contract your pool...
5) see 4.

