views:

102

answers:

0

Hey all!

I'm pretty fresh in the game of C# and .NET so I found some exercises on the net. More specifically an asynchronous web server. I'm currently having some problems with getting the callbacks to fire. Socket.BeginReceive fires its callback the first time, but when I try to do it recursively (like shown on MSDN Tutorial - to get any remaining data) it never fires. I'm currently using .NET 4.0 and VS2010.

Here is my code:

HTTPServer.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Net.Sockets;
using System.Net;
using System.Collections;

namespace UPnPServer.net.HTTPServer
{
    public class HTTPServer
    {
        private TcpListener tcpListener;
        private Thread listenerThread;
        private ManualResetEvent allDone;
        private Boolean kill = false;
        private ArrayList requestHandlers;

        public HTTPServer(int port)
        {
            this.allDone = new ManualResetEvent(true);
            this.tcpListener = new TcpListener(IPAddress.Any, port);
            this.listenerThread = new Thread(new ThreadStart(Listen));
            this.requestHandlers = new ArrayList();
            this.listenerThread.Start();
        }

        private void Listen()
        {
            this.tcpListener.Start();
            while (!this.kill)
            {
                this.allDone.Reset();
                tcpListener.BeginAcceptSocket(new AsyncCallback(AcceptCallback), null);
                this.allDone.WaitOne();
            }
            this.tcpListener.Stop();
        }

        private void AcceptCallback(IAsyncResult ar)
        {
            Socket client = tcpListener.EndAcceptSocket(ar);

            HTTPRequestHandler handler = new HTTPRequestHandler(client);
            handler.RequestProcessed += new HTTPRequestEventHandler(RequestProcessed);
            this.requestHandlers.Add(handler);
            this.allDone.Set();
        }

        private void RequestProcessed(HTTPRequestHandler sender)
        {
            System.Diagnostics.Trace.WriteLine("Ferdig.");
            this.requestHandlers.Remove(sender);
        }
    }
}

HTTPRequestHandler.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.IO;

namespace UPnPServer.net.HTTPServer
{
    public delegate void HTTPRequestEventHandler(HTTPRequestHandler sender);

    public class StateObject
    {
        public Socket Socket = null;
        public const int BufferSize = 4096;
        public byte[] Buffer = new byte[BufferSize];
        public StringBuilder SB = new StringBuilder();
    }

    public class HTTPRequestHandler
    {
        public event HTTPRequestEventHandler RequestProcessed;

        private Socket socket = null;
        private const int bufferSize = 1024;
        private byte[] buffer = new byte[bufferSize];
        private StringBuilder sb = new StringBuilder();

        private void OnRequestProcessed()
        {
            if (this.RequestProcessed != null)
            {
                this.RequestProcessed(this);
            }
        }

        public HTTPRequestHandler(Socket client)
        {
            System.Diagnostics.Trace.WriteLine("Accepted...");
            this.socket = client;
            StateObject state = new StateObject();
            state.Socket = client;
            this.socket.BeginReceive(state.Buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
        }

        private void ReadCallback(IAsyncResult ar)
        {
            StateObject state = (StateObject)ar.AsyncState;
            System.Diagnostics.Trace.WriteLine("Hmm...");
            int read = 0;
            read = this.socket.EndReceive(ar);

            System.Diagnostics.Trace.WriteLine(read);

            if (read > 0)
            {
                this.sb.Append(Encoding.ASCII.GetString(this.buffer, 0, read));
                this.socket.BeginReceive(state.Buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
                return;
            }
            else
            {
                if (this.sb.Length > 1)
                {
                    String request = this.sb.ToString();
                    this.ProcessRequest(request);
                }
                else
                {

                }
            }
        }

        public void ProcessRequest(String request)
        {
            System.Diagnostics.Trace.WriteLine(request);
            this.socket.Close();
            this.OnRequestProcessed();
        }
    }
}

Please help me out here, as I am about to go insane. Thanks.