Re[3]: Вопрос насчет сокетов
От: Svjat Украина  
Дата: 09.07.07 08:41
Оценка:
Здравствуйте, Tanketka, Вы писали:

T>Только теперь это нужно сделать на C#, и многопоточной,


class Proxy
{
   private Socket ListenerSocket;
   List<ProxySession> Session = new List<ProxySession>();

   public void Start( IPAddress ip, int port )
   {
       Socket ListenerSocket = new Socket();
       ListenerSocket.Bind( new IPEndPoint( ip, port ) );
       ListenerSocket.Listen();
       ListenerSocket.BeginAccept( OnAccept );
   }
    
   private void OnAccept( IAsyncResult ar )
   {
       // создаем новую сессию на входящее соединение от браузера
       ProxySession session = new ProxySession( ListenerSocket.EndAccept( ar ) );

       // подписываемся на события
       //session.OnClosed += OnSessionClosed; 
       //......

       Session.Add( session );
       session.Start();
   }
}

class ProxySession
{
   Socket ClientSocket;
   Dictionnary<string,Socket> ServerSocket = new Dictionnary<string,Socket>();

   public ProxySession( Socket socket ) { ClientSocket = socket; }
   public void Start() { ClientSocket.BeginReceive( ...., OnReceive ); }

   private void OnReceive( IAsynchResult ar )
   {
      try
      {
          ClientSocket.EndReceive( ar );
      }
      catch( SocketException )
      {
          // инициатором закрытия сессии может быть только клентсое соединение
          //  точнее, его разрыв
          CloseSession();      
          return;
      }
      ......
      // тут смотрим запрос от браузера, вытаскиваем хост, на кот. идет запрос
      // и если у нас нет такого в списке подключенных, то 
      //  создаем соотв. новое подключение к веб-серверу
      //  причем это нужно делать при каждом запросе от клиента
      //  т.е. в рамках одной сессии может быть один конект от клиента,
      //  и много подключений к веб-серверам
      Socket server = null;
      if( !ServerSocket.TryGetValue( hostName, out server )  )
      {
          server = new Socket( ... );
          ServerSocket.Add( hostName, server );
      }
      server.BeginSend( ..... );
      ClientSocket.BeginReceive( ...., OnReceive );
   }
}



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

что бы сделать архитектуру гибче:
1. процесс передачи данных выделить в отдельный класс — трансмиттер,
кот. владеет 2-мя сокетами, и просто из одного читает и в другой пишет.
2. Сессия просто владеет списком этих "трансмиттеров"
3. операции по созданию сессий / трансмиттеров вынести в отдельные классы,
и юзать через интерфейсы, типа

new Proxy( (ISessionBuilder)( new ProxySessionBuilder( .. ));
new ProxySession( (IConnectionBuilder)( new ConnectionBuilder() ) );

это позволит сделать внутренюю структуру сессии более гибкой.
поясню: если между нашим прокси и веб-сервером сидит другой прокси,
нет смысла делать много клиентских подключений в одной сессии, достаточно одного.
для этого при создании прокси просто создаеются другой набор билдеров.
уже не говоря о том, что тогда этот прокси можно юзать не только для хттп.
4. прокси отвечает только за передачу данных в бинарном виде.
всю работу по анализу трафика тоже лучше выделить в отдельные классы, и тоже
передавать в сессию / прокси через интерфейсы.

при таком подходе реализация какого-либо протокола — всего лишь новый набор фильтров.


-----
мда, собирался покороче один ............
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.