Hello,
First of all thanks for reading this. I am aiming to create a proxy server to overcome some authentication problems. The idea is to have the server handling the requests to a certain port, appending the right credentials, sending the authenticated request to the desirable address, and giving back the response (bytes) to the client.
For that I created two sockets: a listening socket and a client socket for which I show here, the class definition.
As I have a large volume of information on the requests, I am trying to use asynchronous sockets, so that I wont block the system waiting for an answer.
The RequestState class contains the definitions for the state of the request, including a buffer.
The process results in a serious of callbacks and the order of events is more or less this: the BeginGetResponse calls the RespCallback, where the webrequest to the desirable page is thrown, and it activates the BeginRead, that calls a ReadCallback. The readCallback fills the buffer and then I can either call a synchronous blocking send request (which does not work on IE, for e.g.) or call BeginSend with a callback function. The BeginSend also does not work, since the callback (finish) terminates without actualy sending all the information.
Any tips about what I'm doing wrong?
Thanks in advance,
Jo

Code:
using System;
using System.Net;
using System.IO;
using System.Net.Security;
using System.Net.Sockets;
using System.Threading;
using System.Text;

namespace TEST
{
    // The RequestState class passes data across async calls.
    public class RequestState
    {
        public int BufferSize = 1024;
        public byte[] RequestData;
        public byte[] BufferRead;
        public WebRequest Request;
        public Stream ResponseStream;
        public WebResponse Response;
        public Socket aSocket;

        public RequestState()
        {
            BufferRead = new byte[BufferSize];
            RequestData = new byte[0];
            Request = null;
            aSocket = null;
            //Response = null;
            ResponseStream = null;
        }
    }
    ///////////////////////////////////////////////////////

    public delegate void DestroyDelegate_(ProxyClient client);
    public class ProxyClient : IDisposable
    {
        //public static ManualResetEvent allDone = new ManualResetEvent(false);
        const string myUri="http://DEV309.Dev.cadcorp.net:4326/KmlService/Kml.serv?REQUEST=GetCapabilities";
        //const string myUri = "http://localhost/hello.htm";

        public ProxyClient(Socket ClientSocket, DestroyDelegate_ Destroyer, IPEndPoint MapTo, CredentialCache credCache)
        {
            this.ClientSocket = ClientSocket;
            this.Destroyer = Destroyer;
            this.MapTo = MapTo;
            this.m_credCache = credCache;
            this.m_sendDone = new ManualResetEvent(true);
        }

        private IPEndPoint MapTo
        {
            get
            {
                return m_MapTo;
            }
            set
            {
                if (value == null)
                    throw new ArgumentNullException();
                m_MapTo = value;
            }
        }

        internal Socket ClientSocket
        {
            get
            {
                return m_ClientSocket;
            }
            set
            {
                if (m_ClientSocket != null)
                    m_ClientSocket.Close();
                m_ClientSocket = value;
            }
        }

        public void Dispose()
        {
            try
            {
                ClientSocket.Shutdown(SocketShutdown.Both);
            }
            catch { }
            //Close the sockets
            if (ClientSocket != null)
                ClientSocket.Close();
            //Clean up
            ClientSocket = null;
            if (Destroyer != null)
                Destroyer(this);
        }
 
        /////////////////////////////// WebRequest //////////////////////////////////////////////////////
            private void ReadCallBack(IAsyncResult asyncResult)
            {
                try
                {
                    RequestState myRequestState = (RequestState)asyncResult.AsyncState;
                    Stream responseStream = myRequestState.ResponseStream;
                    int read = responseStream.EndRead(asyncResult);
                    if (read > 0)
                    {
                        //Resize Buffer
                        byte[] newBuffer = new byte[myRequestState.RequestData.Length + read];
                        Buffer.BlockCopy(myRequestState.RequestData, 0, newBuffer, 0, myRequestState.RequestData.Length);
                        Buffer.BlockCopy(myRequestState.BufferRead, 0, newBuffer, myRequestState.RequestData.Length, read);
                        myRequestState.RequestData = newBuffer;

                        IAsyncResult asynchronousResult =
                           responseStream.BeginRead(myRequestState.BufferRead, 0, myRequestState.BufferSize,
                             new AsyncCallback(ReadCallBack), myRequestState);

                    }
                    else
                    {
                        if (myRequestState.RequestData.Length > 0)
                        {
                            myRequestState.aSocket.BeginSend(myRequestState.RequestData, 0, myRequestState.RequestData.Length,SocketFlags.None, new AsyncCallback(Finish), myRequestState);
/*
                            int i = myRequestState.aSocket.Send(myRequestState.RequestData, 0, myRequestState.RequestData.Length, SocketFlags.None);
                            System.Diagnostics.Debug.Write("Sent {0} bytes."+ i+"\n");
                            Dispose();
                            myRequestState.ResponseStream.Close();
 */
                        }
                        //responseStream.Close();
                        //myRequestState.aSocket.Shutdown(SocketShutdown.Both);
                        //myRequestState.aSocket.Close();
                        //allDone.Set();
                    }
                }
                catch (SocketException ex)
                {
                    System.Diagnostics.Debug.WriteLine(ex.ToString());
                    Dispose();
                }
            }

            private void Finish(IAsyncResult asyncResult)
            {
                try
                {
                    RequestState myRequestState = (RequestState)asyncResult.AsyncState;
                    Socket mySocket = myRequestState.aSocket;

                    int Ret = mySocket.EndSend(asyncResult);
                    if (Ret <= 0)
                    {
                        Dispose();
                        myRequestState.ResponseStream.Close();
                   }
                    //m_sendDone.Set();
                }
                catch (SocketException ex)
                {
                    System.Diagnostics.Debug.WriteLine(ex.ToString());
                    Dispose();
                }
            }

            private void RespCallback(IAsyncResult asynchronousResult)
            {
                try
                {
                    RequestState myRequestState = (RequestState)asynchronousResult.AsyncState;

                    WebRequest myWebRequest1 = myRequestState.Request;
                    myRequestState.Response = myWebRequest1.EndGetResponse(asynchronousResult);

                    Stream responseStream = myRequestState.Response.GetResponseStream();
                    myRequestState.ResponseStream = responseStream;

                    IAsyncResult asynchronousResultRead =
                    responseStream.BeginRead(myRequestState.BufferRead, 0, myRequestState.BufferSize,
                    new AsyncCallback(ReadCallBack), myRequestState);
                }
                catch (SocketException ex)
                {
                    System.Diagnostics.Debug.WriteLine(ex.ToString());
                    Dispose();
                }
            }

            public void StartHandshake()
            {
                try
                {
                    WebRequest request = (HttpWebRequest)WebRequest.Create(myUri);
                    request.Credentials = m_credCache;//CredentialCache.DefaultCredentials;
                    RequestState myRequestState = new RequestState();
                    myRequestState.Request = request;
                    myRequestState.aSocket = ClientSocket;

                    // Issue the async request.
                    IAsyncResult r = (IAsyncResult)request.BeginGetResponse(
                       new AsyncCallback(RespCallback), myRequestState);

                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.WriteLine(ex.ToString());
                    Dispose();
                }
            }

            private CredentialCache m_credCache;
            private DestroyDelegate_ Destroyer;
            private Socket m_ClientSocket;
            private IPEndPoint m_MapTo;
            private ManualResetEvent m_sendDone;
    }