Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - .NET

Страница: 1 | 2 | 3 | 4 | 5 | 6 |

 

  Вопрос: русские буквы Добавлено: 21.09.10 15:53  

Автор вопроса:  Ishayahu | Web-сайт: ishayahu.blogspot.com | ICQ: 329944992 

Ответить

  Ответы Всего ответов: 90  

Номер ответа: 46
Автор ответа:
 EROS



Вопросов: 58
Ответов: 4255
 Профиль | | #46 Добавлено: 23.09.10 16:26
Ты встал на светлую сторону силы, юный падован )))

Ответить

Номер ответа: 47
Автор ответа:
 Artyom



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #47 Добавлено: 23.09.10 19:52
AgentFire пишет:
ЗЫ Парни, там хаус вышел.

Как мы можем так просто пойти смотреть Хауса когда В ИНТЕРНЕТЕ КТО-ТО НЕ ПРАВ??????

Ответить

Номер ответа: 48
Автор ответа:
 Artyom



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #48 Добавлено: 23.09.10 20:22
AgentFire пишет:
5. (object sender, EventArgs e). Знаю, задумывался. Но считаю, что мне попроще просто раизить с одним параметром winsock Sender (а в большинстве именно это и нужно), нежели передавать по сути ненужный EventArgs e. Но мнение о дефолтном раизере эвентов я уважаю, и коли настоящие джедаи сие юзают, то я возьму на заметку.

А какое отношение вообще сетевой класс имеет к потокам Windows Forms? Если такая синхронизация и нужна (если нужно данные, полученые из сети показывать на контролах Windows Forms), то это делается через Control.Invoke, и никак не в сетевом классе.

AgentFire пишет:
1. да, BW у меян три, юзаю я их четко и диспозю по ненадобности.

Я не ковырял до конца, но если у тебя там есть необработаное исключение (я не увидел чтоб везде была обработка ошибок), то объект вполне может не задиспозиться.

AgentFire пишет:
3. Base64String - юзал когда не знал о XmlSerializer. да и, по идее, и его я юзать боюсь, т.к. у него внутри разрывы строк, что StreamReader.ReadLine может воспринять некорректно. Сам же Base64String я планирую сжимать Deflate'ом, чтобы работало быстрее и жрало меньше траффика.

Зачем тебе вообще эти переводы строк? Сначала отправляешь длину сообщения, потом само сообщения. Это позволяет обойтись без переводов строк как индикаторов конца сообщения.

AgentFire пишет:
6. "Option Strict On код не компилится, 5 error'ов". Фишка такая, что в коде часто встречаются моменты вроде Dim a = Console.ReadLine. Тип не указан, но студия безошибочно понимает, что я желаю присвоить а тип String. Так что ..

Это называется неявная типизация. Компилятор видит, что ты инициализируешь переменную строковым значением, и делает ей тип String. Это не является ошибкой, и я не про это говорил, а про другие. Поставь вверху Option Strict Off и посмотри в каких местах будет падать - именно в тех где ты выполняешь неявное приведение типов, или Late Binding.

Ответить

Номер ответа: 49
Автор ответа:
 Artyom



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #49 Добавлено: 23.09.10 20:29
EROS пишет:
Единственное что могу добавить что использование Base64 реально не оправдано, т.к. он на 30% увеличивает объем передаваемой информации.. Xml тоже не вариант - слишком много мусора..

Скажи это авторам SOAP.
При межплатформенных коммуникациях это один из самых оптимальных вариантов. Не нужно разбираться с вырванивание слов в 4-байтных переменных, форматах дат и кодировках. XML он, как говорится, и в африке XML.

EROS пишет:
Оправдан чистый байтовый массив.. Разрабтай свой протокол и парси на другой стороне в соответствии с протоколом

О_О

20 лет шли от чистого бинарного протокола к чистому XML, а теперь обратно на бинарный протокол предлагаешь?

Ответить

Номер ответа: 50
Автор ответа:
 Artyom



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #50 Добавлено: 23.09.10 20:32
Вообще в потоки ты совсем не к месту уперся. Почти любой TCP-сервер, написаный на потоках, намертво DOS-ится за минуту (кроме того который сразу отклчюает клиента после подключения).
Джедаи делюат на TCP-серверы на осинхронных операциях ввода-вывода

Ответить

Номер ответа: 51
Автор ответа:
 EROS



Вопросов: 58
Ответов: 4255
 Профиль | | #51 Добавлено: 23.09.10 22:20
20 лет шли от чистого бинарного протокола к чистому XML, а теперь обратно на бинарный протокол предлагаешь?

ну знаешь.. одно дело передать 2-3 объекта клиенту в сериализованном виде - это один разговор, а когда 3000 объектов (как в моем случае) то начинаешь изворачиваться как можешь, чтоб уменьшить трафик

Ответить

Номер ответа: 52
Автор ответа:
 AgentFire



ICQ: 192496851 

Вопросов: 75
Ответов: 3178
 Профиль | | #52 Добавлено: 24.09.10 10:01
Artyom пишет:
Если такая синхронизация и нужна (если нужно данные, полученые из сети показывать на контролах Windows Forms), то это делается через Control.Invoke, и никак не в сетевом классе.

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

Ответить

Номер ответа: 53
Автор ответа:
 Artyom



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #53 Добавлено: 24.09.10 11:47
AgentFire, жаль что ты недал примера использования твоего винсока в качестве сервера, а разбираться как его в таком режиме запустить нет времени.
Вот один мой старый примре сервера. Под 4.0, но под 3.5 должен пойти. С определенной точки зрения, которая нас сейчас интерисует, работает так же как и твой винсок.

  1.     class Program
  2.     {
  3.         static void Main(string[] args)
  4.         {
  5.             System.Threading.Thread AcceptThread = new System.Threading.Thread(AcceptMethod)
  6.                 {
  7.                     IsBackground = true,
  8.                     Priority = System.Threading.ThreadPriority.Lowest
  9.                 };
  10.             AcceptThread.Start();
  11.  
  12.             Console.ReadLine();
  13.         }
  14.  
  15.         private static List<NetClient> NetClients = new List<NetClient>();
  16.  
  17.         private static void AcceptMethod()
  18.         {
  19.             TcpListener listener = new TcpListener(IPAddress.Any, 999);
  20.             listener.Start();
  21.             while (true)
  22.             {
  23.                 TcpClient client = listener.AcceptTcpClient();
  24.                 NetClient netClient = new NetClient(client);
  25.                 
  26.                 lock (NetClients)
  27.                     NetClients.Add(netClient);
  28.                 Console.WriteLine("Подключился клиент. Всего {0}", NetClients.Count);
  29.                 netClient.Start();
  30.             }
  31.         }
  32.  
  33.         private class NetClient
  34.         {
  35.             private TcpClient Client;
  36.             private NetworkStream Stream;
  37.  
  38.             System.Threading.Thread readThread;
  39.             public NetClient(TcpClient client)
  40.             {
  41.                 this.Client = client;
  42.             }
  43.  
  44.             public void Start()
  45.             {
  46.                 Stream = Client.GetStream();
  47.  
  48.                 readThread = new System.Threading.Thread(ReadMethod)
  49.                     {
  50.                         IsBackground = true,
  51.                         Priority = System.Threading.ThreadPriority.Lowest
  52.                     };
  53.                 readThread.Start();
  54.             }
  55.  
  56.             private void ReadMethod()
  57.             {
  58.                 try
  59.                 {
  60.                     byte[] buffer = new byte[100];
  61.                     int length;
  62.                     do
  63.                     {
  64.                         length = Stream.Read(buffer, 0, buffer.Length);
  65.                     } while (length > 0);
  66.                 }
  67.                 catch { }
  68.                 finally
  69.                 {
  70.                     Client.Close();
  71.                     Stream.Dispose();
  72.                     lock (NetClients)
  73.                         NetClients.Add(this);
  74.                     Console.WriteLine("Отключился клиент. Всего {0}", NetClients.Count);                  
  75.                 }
  76.             }
  77.         }
  78.     }

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

Теперь берем берем прогармму, которая подключает клиентов к серверу. Клиент подключается, никаких данных не передает, просто висит.
  1.     class Program
  2.     {
  3.         static void Main(string[] args)
  4.         {
  5.             System.Threading.Thread.Sleep(2000);
  6.  
  7.             List<TcpClient> clients = new List<TcpClient>();
  8.             while (true)
  9.             {
  10.                 try
  11.                 {
  12.                     TcpClient client = new TcpClient("127.0.0.1", 999);
  13.                     clients.Add(client);
  14.                     Console.WriteLine("Запущено клиентов: {0}", clients.Count);
  15.                 }
  16.                 catch { System.Threading.Thread.Sleep(100); }
  17.             }
  18.         }
  19.     }


Запускаем. Конец.... непредсказуем.

  1. Подключился клиент. Всего 1355
  2. Подключился клиент. Всего 1356
  3. Подключился клиент. Всего 1357
  4. Подключился клиент. Всего 1358
  5.  
  6. Unhandled Exception: OutOfMemoryException.


Откуда OutOfMemoryException если у нас никакие данные не используются и не передаются? Куда могла утечь память?
У нас есть 1300 объектов TcpClient, NetworkStream, NetClient и каких-то сопутствующих. Но они весят немного и не могут съесть ощутимо много памяти.
Есть буферы данных, мы для каждого клиента создаем буфер размером 100 байт, на всех клиентов в сумме выходит чуть больше 100 кб, т.е. тут тоже потери нет.
Буферы также есть в Socket, к которому подключен TcpClient, по умолчанию, кажется, 8кб. В сумме это еще всего 10 мб.

Еще один ресурс, который не учтен - это потоки. 1300 потоков. Причем каждый поток получает 1 мб стека. А это уже 1.3 ГБ.
В результате при очередной попытке запустить новый поток память кончается и приложение падает.

И любая реализация TCP-сервера, основаная на потоках (причем не важно как именно, напрямую на Thread, на ThreadPool, на BackgroundWorker или на чем еще) не сможет обслуживать большое количество клиентов. Отличие в том что в случае использование ThreadPool приложение не упадет, а просто перестанет принимать подключения клиентов, так как ThreadPool заполнится (порядка 1000 потоков) и новые потоки просто не будут создаваться.
Даже если не планируется что сервером будут пользоваться большое кол-во клиентов, нужно понимать что при желании любой недоброжелатель может подключить к серверу фиктивных клиентов и он упадет.

Ответить

Номер ответа: 54
Автор ответа:
 Artyom



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #54 Добавлено: 24.09.10 11:57
А если в сетевом модуле сделать встроенную синхронизацию, то никакого профита не получишь, кроме того, поскольку все запросы будут еще и завязаны на единственный UI поток, получаем ряд возможностей для различных дедлоков и т.п.

Ответить

Номер ответа: 55
Автор ответа:
 AgentFire



ICQ: 192496851 

Вопросов: 75
Ответов: 3178
 Профиль | | #55 Добавлено: 24.09.10 12:46
ты не рассмотрел вариант, когда я тупо поставлю ограничение в, скажем, 500 подключений. И ничего не не поделаешь

Ответить

Номер ответа: 56
Автор ответа:
 Artyom



Разработчик

Вопросов: 130
Ответов: 6602
 Профиль | | #56 Добавлено: 24.09.10 12:48
Ставь любое ограничение. Я подключу 500 фиктивных клиентов, после чего клиент, которому действительно нужно работать с сервером уже не сможет подключиться.

Ответить

Номер ответа: 57
Автор ответа:
 EROS



Вопросов: 58
Ответов: 4255
 Профиль | | #57 Добавлено: 24.09.10 12:57
считаю нужным иметь синхронизацию в самом классе, чтобы вызывать евенты из изначального потока.

эээээмм.. как бы так выразиться чтоб не начать очередной холивар..
AgentFire, без обид, но ты пока еще мыслишь реалиями VB6, мыслишь модулями. Как тебя там научили, что весь схожий функционал надо пихать в один модуль, так же ты и тут поступаешь. А между тем ООП предполагает несколько другой подход. Если говорить своими словами то можно его трактовать в таком виде(как я это понимаю): Если у класса слишком много ответственности, то его надо распилить. И вот почему:
Твой класс надо распилить на несколько мелких и более узкоспециализированных. Один будет читать данные, второй писать, третий примать подключения , четвертый это объект конфигурации для первых трех.. это кагбэ в общем виде. Кроме этого должен быть некий контроллер который будет связывать все эти классы воедино и обеспечивать всю работу между ними. А теперь смотри.. если ты задумаешь сделать эти операции асинхронными, то тебе придется все это реализовывать и в "читателе" и "писателе", и становится очевидным, что обеспечении асинхронности надо выносить на другой уровень.. на уровень контроллера. Помимо всего этого, если ты захочешь несколько расширить,скажем, своего читателя, то ты сможешь с легкостью от него наследоваться (учитывая что там нет реализации асинхронности) и сможешь допилить его под новые задачи. Улавливаешь мысль? А в таком виде как у тебя - он "одноразовый".
Подводя итог снова напомню старую мудрость: Мухи отдельно, а котлеты отдельно.. Именно поэтому Artyom тебе сказал, что в сетевом классе не должно быть реализаци асинхронности., это должно быть на другом уровне.. а на каком - решать тебе. И еще +1 к его словам о том, что тут потоки(и тем более BW) не нужны, нужны асинхронные операции чтения/записи.

Ответить

Номер ответа: 58
Автор ответа:
 AgentFire



ICQ: 192496851 

Вопросов: 75
Ответов: 3178
 Профиль | | #58 Добавлено: 24.09.10 14:36
у меня и так есть главный класс, есть подклассы, которыми он управляет, и у каждого имеется один Winsock, которым они управляют. Предлагаете еще и винсок делать общим для более мелких ?

Ответить

Номер ответа: 59
Автор ответа:
 VβÐUηìt



Вопросов: 246
Ответов: 3333
 Web-сайт: смекаешь.рф
 Профиль | | #59
Добавлено: 24.09.10 15:21
А куда тринадцать смылась?

Ответить

Номер ответа: 60
Автор ответа:
 EROS



Вопросов: 58
Ответов: 4255
 Профиль | | #60 Добавлено: 24.09.10 15:59
Предлагаете еще и винсок делать общим для более мелких ?

а угадай с одного раза..

Ответить

Страница: 1 | 2 | 3 | 4 | 5 | 6 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам