Не работает Proxy сервер C#
От: Rvnikita  
Дата: 25.02.08 09:04
Оценка:
Есть код:


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


namespace Proxy
{
    class Program
    {
        public static ManualResetEvent allDone = new ManualResetEvent(false); //ручной ивент, чтобы не сбивались

        static void Main(string[] args)
        {
            

            IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
            IPAddress ipAddress = ipHostInfo.AddressList[0];
            IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);

            try
            {
                Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                listener.Bind(localEndPoint); //бинд
                listener.Listen(1000); //максимальная очередь
                while (true)
                {
                    Console.WriteLine("Waiting for a connection");

                    // Set the event to nonsignaled state.
                    allDone.Reset();

                    listener.BeginAccept(new AsyncCallback(AcceptCallback),listener); //в отдельный поток обработку

                    allDone.WaitOne(); //ждем пока обработчик не начнется          
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
        }

        public static void AcceptCallback(IAsyncResult ar)
        {
            byte[] bytes = new Byte[1024]; //сюда будем принимать (причем дважды .))

            

            Socket listener = (Socket)ar.AsyncState;
            Socket handler = listener.EndAccept(ar);

            // Signal the main thread to continue.
            allDone.Set();

            string data = null; //отчищаем

            // An incoming connection needs to be processed.
            while (true)
            {
                bytes = new byte[1024];
                int bytesRec = handler.Receive(bytes);
                data += Encoding.ASCII.GetString(bytes, 0, bytesRec);

                if (bytesRec < 1024) //если не забили весь буфер
                {
                    break;
                }
            }

            //data хранит наш запрос, осталось распарсить .)
            string[] data_strings = data.Split(new String[] { "\r\n" }, StringSplitOptions.None);
            string data_host = null;

            if (data_strings[0].Length > 3)
            {
                string data_address = data_strings[0].Substring(3, data_strings[0].IndexOf("HTTP") - 4).Trim(); //получаем адрес
            }
            if (data_strings[0].Length > 6)
            {
                data_host = data_strings[2].Substring(6, data_strings[2].Length - 6);
            }


            try
            {
                if (data_host != null)
                {
                    IPHostEntry ipHostInfo = Dns.GetHostByName(data_host);
                    IPAddress ipAddress = ipHostInfo.AddressList[0];
                    IPEndPoint remoteEndPoint = new IPEndPoint(ipAddress, 80);

                    Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); //сокет соединения с удаленным сайтом

                    client.Connect(remoteEndPoint);
                    client.Send(Encoding.ASCII.GetBytes(data)); //отправляем то что получили от нашего пользователя


                    while (true)
                    {
                        bytes = new byte[1024];
                        int bytesRec = client.Receive(bytes);

                        ManualResetEvent s = new ManualResetEvent(false);
                        s.WaitOne(1000, false);

                        //Console.WriteLine(Encoding.ASCII.GetString(bytes, 0, bytesRec));

                        handler.Send(bytes);

                        if (bytesRec < 1024) //если не забили весь буфер
                        {
                            break;
                        }
                    }

                    client.Shutdown(SocketShutdown.Both);
                    client.Close();
                }
                handler.Shutdown(SocketShutdown.Both);
                handler.Close();
            }
            catch(Exception e)
            {
                handler.Shutdown(SocketShutdown.Both);
                handler.Close();
                Console.WriteLine(e.ToString());
            }
        }
    }
}


Если ставить брейкпоинт и пошагово выполнять проект то все с горем пополам работает, и страничка почастям грузится.
Если же бряк убирать и в динамическом режиме работать, ничего не работает.
Или загружается одна страница, вторая уже нет.

Проверка происходит следующим образом:
запускается браузер опера, у него прописывается вместо прокси ип сервера и пытается загрузить что либо.

Сервер (по идеи) должен получить по сокету запрос, его распарсить (вытащить оттуда ип хоста) и ему перенаправляет запрос, полученный ответ кидает обратно клиенту.

Спасибо.
Re: Не работает Proxy сервер C#
От: mihailik Украина  
Дата: 26.02.08 07:55
Оценка: 8 (1)
Очень трудно написать даже простой корректный HTTP-сервер. Смешение парсинга и многопоточности в одной задаче даёт суровую проблему.

Поэтому вот тебе готовый прокси-сервер на C#, лицензия позволяет произвольно использовать в коммерческих/некоммерческих приложениях.

http://www.mentalis.org/soft/projects/proxy/


У тебя там превышено маскимально допустимое число багов.

R>Есть код:


R> if (bytesRec < 1024) //если не забили весь буфер

R> {
R> break;
R> }

А если забили весь буфер, то выкидываем полученные 1024 байта.


R> if (data_strings[0].Length > 6)

R> {
R> data_host = data_strings[2].Substring(6, data_strings[2].Length — 6);
R> }

Адрес хоста всегда последние 6 символов 2-го HTTP-заголовка.



R> ManualResetEvent s = new ManualResetEvent(false);

R> s.WaitOne(1000, false);

Квантовое програмирование. Создали событие, вот сидим ждём, что оно само перепрыгнет из не-сигнализированного состояния в сигнализированное.

Ну правильно, событие это же примитив, элементарная частица. Туннельный эффект на быстрых процессорах может обнаружиться.


R> handler.Send(bytes);


R> if (bytesRec < 1024) //если не забили весь буфер

R> {
R> break;
R> }

При чём здесь принимающий буфер?
Re[2]: Не работает Proxy сервер C#
От: _FRED_ Черногория
Дата: 26.02.08 08:02
Оценка:
Здравствуйте, mihailik, Вы писали:

R>> ManualResetEvent s = new ManualResetEvent(false);

R>> s.WaitOne(1000, false);

M>Квантовое програмирование. Создали событие, вот сидим ждём, что оно само перепрыгнет из не-сигнализированного состояния в сигнализированное.


M>Ну правильно, событие это же примитив, элементарная частица. Туннельный эффект на быстрых процессорах может обнаружиться.


Help will always be given at Hogwarts to those who ask for it.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.