private void CloseClientSocket(SocketAsyncEventArgs e)
        {
            AsyncUserToken token = (AsyncUserToken)e.UserToken;

            try
            {
                token.Socket.Shutdown(SocketShutdown.Send);
            }
            catch (Exception ex)
            {
            }

            token.Socket.Close();
            Threading.Interlocked.Decrement(ref _numConnections);
            _maxNumberAcceptedClients.Release();
            _readWritePool.Push(e);
            Console.WriteLine(_readWritePool.Count);
        }
 private void ProcessSend(SocketAsyncEventArgs e)
 {
     if (e.SocketError == SocketError.Success)
     {
         AsyncUserToken token = (AsyncUserToken)e.UserToken;
         // ' TODO: LEFT OFF HERE
         // Dim x As SocketAsyncEventArgs = _readWritePool.Pop
         // x.UserToken = token
         // Dim willRaiseEvent As Boolean = token.Socket.ReceiveAsync(e)
         CloseClientSocket(e);
         // If Not willRaiseEvent Then
         //     ProcessReceive(e)
         // End If
     }
     else
     {
         CloseClientSocket(e);
     }
 }
        // '' <summary>
        // '' Handles the client request/response cycle, replying to a request with a response by default. May be overridden during implementation for custom response handling.
        // '' </summary>
        // '' <param name="req"></param>
        // '' <param name="res"></param>
        // '' <param name="client"></param>
        // '' <remarks></remarks>
        private void _HandleRequest(Request req, Response res, SocketAsyncEventArgs client)
        {
            //  serve the requested resource from the output cache or from disk; better yet, store the entire response and serve that up to save some time
            if (OutputCache.ContainsKey(req.AbsoluteUrl))
            {
                Response cachedResponse = (Response)OutputCache[req.AbsoluteUrl];
                res = cachedResponse;
                DebugMessage(("Serving resource from cache: "
                              + (req.AbsoluteUrl + ".")), DebugMessageType.UsageMessage, "ClientRequest event");
                //  TODO: we might want to move the res.GetAllBytes call into the Else condition here so it doesn't get called again for an already cached response
            }
            else
            {
                //  serve the file from disk
                //  TODO: depending on TransferMethod requested by the client, we should implement StoreAndForward or ChunkedEncoding, but for now we will just use StoreAndForward
                if (IO.File.Exists(req.AbsoluteUrl))
                {
                    //  determine how to the process the client's request based on the requested uri's file type
                    //  this is where we might load a resourince, maybe using Interops to parse dynamic scripts (e.g. PHP and ASP.NET)
                    if (req.MimeType.Handler == "")
                    {
                        //  no custom handler for this mimetype, serve as a static file
                        res.ContentType = req.MimeType.Name;
                        // GetContentType(req.AbsoluteUrl)
                        res.SetContent(IO.File.ReadAllBytes(req.AbsoluteUrl));
                        res.StatusCode = 200;
                    }
                    else
                    {
                        //  TODO: there is a custom handler assigned to this filetype, but handlers are not implemented yet so we just serve it as a static file
                        res.ContentType = req.MimeType.Name;
                        // GetContentType(req.AbsoluteUrl)
                        res.SetContent(IO.File.ReadAllBytes(req.AbsoluteUrl));
                        res.StatusCode = 200;
                    }

                    //  cache the response for future use to improve performance, avoiding the need to process the same response frequently
                    if (OutputCache.ContainsKey(req.AbsoluteUrl))
                    {
                        OutputCache.Add(req.AbsoluteUrl, res);
                    }
                    else
                    {
                        //  page not found, return 404 status code
                        res.StatusCode = 404;
                    }
                }

                //  send the response to the client who made the initial request
                byte[] responseBytes = res.GetResponseBytes();
                // Dim sendEventArg As SocketAsyncEventArgs = _readWritePool.Pop
                // Dim ar As AsyncUserToken = client
                // sendEventArg.UserToken = ar
                // sendEventArg.SetBuffer(responseBytes, 0, responseBytes.Length)
                client.SetBuffer(responseBytes, 0, responseBytes.Length);
                AsyncUserToken token          = (AsyncUserToken)client.UserToken;
                bool           willRaiseEvent = token.Socket.SendAsync(client);
                if (!willRaiseEvent)
                {
                    //  TODO: this never fires!! why not?
                    Beep();
                }

                //  handle keep-alive or disconnect
                if (res.Headers["Connection"] == "keep-alive")
                {
                    //  receive more from the client
                    // Dim readEventArgs As SocketAsyncEventArgs = _readWritePool.Pop
                    // token.Socket.ReceiveAsync(readEventArgs)
                }
                else
                {
                    // token.Socket.Disconnect(False)
                    // token.Socket.Close()
                    //  TODO: maybe move this into the CompleteReceive where we call ReceiveAsync...
                    CloseClientSocket(client);
                }

                // Dim sendState As New AsyncSendState(client)
                // sendState.BytesToSend = responseBytes
                // sendState.Tag = req.AbsoluteUrl
                // If res.Headers["Connection") = "keep-alive" Then
                //     sendState.Persistent = True
                // End If
                // Try
                //     client.BeginSend(responseBytes, 0, responseBytes.Length, SocketFlags.None, AddressOf CompleteSend, sendState)
                // Catch ex As Exception
                //     LogEvent("Could not send data to this client. An unhandled exception occurred.", LogEventType.UsageMessage, "ClientRequest", ex.Message)
                // End Try
                // ' call BeginReceive again, so we can receive more data from this client socket (either not needed for http server or only for persistent connections...reimplement for binary rpc server)
                // If sendState.Persistent = True Then
                //     Dim receiveState As New AsyncReceiveState
                //     receiveState.Socket = client
                //     Try
                //         receiveState.Socket.BeginReceive(receiveState.Buffer, 0, gBufferSize, SocketFlags.None, New AsyncCallback(AddressOf CompleteRequest), receiveState)
                //     Catch ex As Exception
                //         LogEvent("Could not receive more data from this client. An unhandled exception occurred.", LogEventType.UsageMessage, "ClientRequest", ex.Message)
                //     End Try
                // End If
            }
        }