Newsgroups : Borland : borland.public.delphi.internet.winsock : 2006 Jul : AcceptEx again. Is it me or are M$ just......
| Subject: | AcceptEx again. Is it me or are M$ just...... |
| Posted by: | "Martin James" (mjames_falc..@dial.pipex.com) |
| Date: | Thu, 20 Jul 2006 12:36:20 |
I had another look at AcceptEx to try and improve the performance of my
server. This Winsock API has the wonderful, (?), facility to auto-receive
the first data chunk from a client and return it with the completion port
entry, so relieving us poor developers from having to issue a first WSARecv
with a small buffer. Great!
Then:
The server is open to DOS attacks and cannot detect zombie clients.
Furthermore, any protocol that requires that the server issue a
'command-prompt' before getting any bytes from a client will not work
because no notification is received on accept until some data comes in from
the client. Brilliant!
The zombie/DOS problem can be solved by timing out the sockets. This means
either a CPU-wasting socket-polling loop in the listening thread, (this can
be done periodically because GetQueuedCompletionStatus has a timeout
parameter), a load of each socket object onto my seperate general-timeout
thread or a dedicated thread that uses WSAEventSelect to detect an accept
before any data is sent. Some of these solutions have problems with
race-conditions that will be difficult to solve since the kernel thread that
is doing the accepting cannot be made to call a CS before changing the
socket connection state. Typical soddin' M$ mess.
The server-initiated protocol is even more awkward. In a general-purpose
server, an accept requires a trip to the Protocol-Handler to fire the
'OnConnect' event, just in case the PH wants to issue a prompt to the
client. This almost forces the use of a thread that is not the listening
thread, waiting using WSAEventSelect, to fire this event. This is not
trivial because any new socket issued to AcceptEx has to be communicated to
the WES thread. We might be off to the races again where an AcceptEx
completion is returned before the WES thread has started to wait for accept
on the socket. Another M$ mess that probably requires another raft of
socket states, proected by CS, to solve in a safe manner.
Would it have been so difficult for M$ to have included a timeout on
AcceptEx or an 'OnAccept' completion routine that is called before the data
wait starts? Why should I have to add all this complexity and waste?
Polling, undetermined states across extra threads, I don't want it!
Anyone got any better ideas before I start fighting with the WS API again?
Rgds,
Martin