powered by simpleCommunicator - 2.0.55     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / TCP\SSL-Server на C#
22 сообщений из 47, страница 2 из 2
TCP\SSL-Server на C#
    #38468946
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В общем, примерно понятно.

Точные сроки вам никто не скажет, мой оффер такой:

Если исходить из предположения, что будет а) нормально сформулированное ТЗ б) контактное лицо для оперативных ответов по возникающим моментам в) доступ к тестовому окружению (сервер, БД, клиенты), то сроки от 1 недели до месяца.

Предварительно: клиенты - балансировщик nginx - транспортный сервер (в виде dll, запускаемый внутренним менеджером) - БД.
...
Рейтинг: 0 / 0
TCP\SSL-Server на C#
    #38468958
JustOxlamon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Arm79В общем, примерно понятно.

Точные сроки вам никто не скажет, мой оффер такой:

Если исходить из предположения, что будет а) нормально сформулированное ТЗ б) контактное лицо для оперативных ответов по возникающим моментам в) доступ к тестовому окружению (сервер, БД, клиенты), то сроки от 1 недели до месяца.

Предварительно: клиенты - балансировщик nginx - транспортный сервер (в виде dll, запускаемый внутренним менеджером) - БД.

Ок, ну я тогда отпишусь на мыло, что есть в контактных данных и можно начинать договариваться?
...
Рейтинг: 0 / 0
TCP\SSL-Server на C#
    #38468972
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JustOxlamon,

Угу.
...
Рейтинг: 0 / 0
TCP\SSL-Server на C#
    #38468989
netivan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JustOxlamonnetivanJustOxlamon,

теперь мне не очень понятен суть клиента и сервера. Сервер - это хрень, которая слушает TCP порты и отвечает на них в зависиомсти от клиента (видимо ответ берется из базы), или как? Один клиент - один порт, или один порт- Х клиентов (судя по примеру)... я бы вообще сделал через WCF это надо. Мне кажется в итоге и получится некий велосипед... А задача на самом деле очень интересная и как правильно заметил выше Арм, оч много можно всего накрутить. Вопрос именно в требовании.

Я бы тоже писал на WCF\tcp.net и был бы счастлив т.к. строгая типизация, норм трафик и ваще полная няшка. Но тут на клиент мы не влияем никак. Поэтому протокол уже есть и фиксирован.

Много клиентов, один сервер, слушает один порт.
Самих серверов может быть до 6 штук.

Действительно требуется только примерно вот это:

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
interface Client{
  string Login {get;}

  void OnConnect();
  void OnDisconnect();
  void OnError( int Code );
  void OnPaсketReceived( Packet p );

  void WritePacket( Packet p );
}

interface Server{
  void Start(int Port);
  void Stop();
  
  bool ForceDisconnectUser( string Login );
  void SendPacket( string ToLogin, Packet p );
}




+/- детали НЕ усложняющие разработку. Которые будут оговорены ВНАЧАЛЕ во время написания совместного ТЗ, возможно по скайпцу. Остальное мы наговнокодим сами )
Сервер - обрабатывает 1 порт и передает его нужному клиенту ( опередялет по сообщению), клиент обрабатывает сообщение и отдает его обратно, так? Тогда у меня есть тоже мысли :) В "лоб" я бы не стал тут делать.
...
Рейтинг: 0 / 0
TCP\SSL-Server на C#
    #38469210
Alex Kuznetsov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JustOxlamon,

Насколько я понял из описаний и "реализации", ежели клиент зацепился за соединение, то тупо держит его всё время пока сам не отвалится, либо его не отвалят... - по ресурсам это чуть более чем дохрена...

Далее, все клиенты в одном Application Domain - это очень плохо. Поймал кто-нибудь необработанный Exception и практически можно завалить весь "сервер" с остальными клиентами. Отсюда вывод - работа с клиентом должна быть вынесена в отдельный AppDomain, соответственно плагинная архитектура.

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

И ещё, если по количеству соединений вроде как ограничения могут быть преодолены, то вот по количеству потоков - ну тут уж прямо и не знаю... 10К потоков одновременно... возвращаемся про "чуть более чем дохрена ресурсов"...
...
Рейтинг: 0 / 0
TCP\SSL-Server на C#
    #38469344
JustOxlamon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Alex Kuznetsov,

Да, со всем согласен. Опыта у меня в такой разработке чуть меньше чем нету. Ранее всю черную работу делал за меня WCF\IIS.
На текущий момент договорились работать с Arm79.
Поэтому обсуждение можно пока свернуть, спасибо всем кто отписался.
...
Рейтинг: 0 / 0
TCP\SSL-Server на C#
    #38469406
Alex Kuznetsov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JustOxlamon,
Это то что пришло навскидку, и заодно предупредил о возможных подводных камнях...

И ещё мысли в слух: С точки зрения оптимизации нагрузки, сервис должен крутиться на машинке без всяких там IIS+SQL и т.д. , т.е. только сервис + брандмауэр. Соответственно сервис должен иметь возможность управляться извне... подумайте также и над этим...

Кстати, ещё один небольшой совет: для реализации плагинной архитектуры я бы отказался от использования интерфейсов, в пользу единого абстрактного класса, от которого будут порождаться конкретные реализации, работающие с клиентом...
Так можно больше контроля сделать...
Слой работы с базой также лучше вынести в отдельный AppDomain...

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

Единственная сложность в данном случае - это межпроцессные коммуникации...

Учтите, что за неделю такие вещи сложно реализовать.
Например, у меня на реализацию с нуля нормального SMPP клиента работающего в качестве шлюза ушло порядка 3-х месяцев по 2-3 часа в день работы над проектом. Так что...

PS. Даа... интересный должен быть проект...
...
Рейтинг: 0 / 0
TCP\SSL-Server на C#
    #38469448
JustOxlamon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Alex KuznetsovJustOxlamon,
Это то что пришло навскидку, и заодно предупредил о возможных подводных камнях...

И ещё мысли в слух: С точки зрения оптимизации нагрузки, сервис должен крутиться на машинке без всяких там IIS+SQL и т.д. , т.е. только сервис + брандмауэр. Соответственно сервис должен иметь возможность управляться извне... подумайте также и над этим...

Кстати, ещё один небольшой совет: для реализации плагинной архитектуры я бы отказался от использования интерфейсов, в пользу единого абстрактного класса, от которого будут порождаться конкретные реализации, работающие с клиентом...
Так можно больше контроля сделать...
Слой работы с базой также лучше вынести в отдельный AppDomain...

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

Единственная сложность в данном случае - это межпроцессные коммуникации...

Учтите, что за неделю такие вещи сложно реализовать.
Например, у меня на реализацию с нуля нормального SMPP клиента работающего в качестве шлюза ушло порядка 3-х месяцев по 2-3 часа в день работы над проектом. Так что...

PS. Даа... интересный должен быть проект...

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

А слой с БД почему надо выносить в отдельный AppDomain? есть какие-то предпосылки к этому?

И еще вопрос, как вы реализовали выгрузку модулей? У дотнета с эти проблемы. Как я понимаю только используя AppDomain?
Но тут вопрос скорости встает. В нашем проекте очень-очень-очень хотелось бы реализовать подобное. Пока решается это рестартом, из-за того что 2 версии одной длл не могут быть загружены (мы не пользовали appdomain, а просто assembly.load)
...
Рейтинг: 0 / 0
TCP\SSL-Server на C#
    #38469451
JustOxlamon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В идеале я бы хотел подобную архитектуру:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
//processorX_xx <- это как бы объект класса (instance) processorX

//Стартовая, чистая загрузка:

(processorA, processorB, processorC )

//Заходят клиенты, запускают свои обработчики (создают объекты классов):

cli_00: (processorA_00, processorB_00 )
cli_01: (processorA_01 )

//обнаружено обновление DLL с компонентом processorA, оно подгружается

(processorA, processorB, processorC, processorA_new )
//Клиенты продолжают работать, для них ничего не поменялось

cli_00: (processorA_00, processorB_00 )
cli_01: (processorA_01 )
//заходит еще один клиент, запускает обработчики
cli_02: (processorA_new_00 )

//выходит 0 и 1 клиент
cli_02: (processorA_new_00 )

//система обнаруживает, что processorA никто не использует и есть новая версия, можно освободить память
...
Рейтинг: 0 / 0
TCP\SSL-Server на C#
    #38469506
netivan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alex Kuznetsov,

очереди тоже думал, но в случае, если соединение держится не вижу в них смысла особого.
Каждый плагин в домене это перебор )
...
Рейтинг: 0 / 0
TCP\SSL-Server на C#
    #38469526
Фотография Нахлобуч
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Быть может, стоит посмотреть в сторону Node.js?
...
Рейтинг: 0 / 0
TCP\SSL-Server на C#
    #38469752
Alex Kuznetsov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JustOxlamon,

Покажу кусочки кода:
MyProcessorFactory
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
...
        public void AddAppProcessor(short anID, string aLibraryPath, string aClassName)
        {
            if (aPartnerName == null) return;
            if (aLibraryPath == null) return;
            if (aClassName == null) return;
            String sAppDomainName = aClassName.Replace('.', '_') + "_Domain";
            if (IsAppProcessorHere(aClassName)) return;

            try
            {
                AppDomainSetup setup = AppDomain.CurrentDomain.SetupInformation;
                System.Security.Policy.Evidence evidence = AppDomain.CurrentDomain.Evidence;
                AppDomain newDomain = AppDomain.CreateDomain(sAppDomainName, evidence, setup);

                MyProcessorAssembly mypa = (MyProcessorAssembly)newDomain.CreateInstanceAndUnwrap(
                                                                    typeof(MyProcessorAssembly).Assembly.FullName,
                                                                    typeof(MyProcessorAssembly).FullName);
                MyAppProcessor myapp = new MyAppProcessor();
                if (mypa.LoadAssembly(anID, aLibraryPath, aClassName))
                {
                    mypa.AddAllowedNumbers(fDBModule.GetProcessorAllowedNumbers(anID));
                    myapp.domain = newDomain;
                    myapp.processorAssembly = mypa;

                    myapp.AppProcessorName = sAppDomainName;
                    lock (oProcLock)
                    {
                        fAppProcessors.Add(myapp);
                    }
                }
                else
                {
                    System.AppDomain.Unload(newDomain);
                    newDomain = null;
                    mypa.StopAssembly();
                    mypa = null;
                    myapp = null;
                }
            }
            catch (Exception ex)
            {
                Log("Не могу загрузить процессор " + aClassName + " из " + aLibraryPath, ex);
            }
        }

...
        public bool IsAppProcessorHere(string aClassName)
        {
            if (aClassName == null) return false;
            string lName = aClassName.Replace('.', '_') + "_Domain";
            lock (oProcLock)
            {
                foreach (MyAppProcessor appd in fAppProcessors)
                    if (appd.AppProcessorName.Equals(lName))
                        return true;
            }
            return false;
        }
...

        public void StopAppProcessor(string aClassName)
        {
            if (aClassName == null) return;
            String sAppDomainName = aClassName.Replace('.', '_') + "_Domain";
            int idx = -1;
            lock (oProcLock)
            {
                idx = GetAppProcessorIndex(sAppDomainName);
                if (idx >= 0)
                {
                    fAppProcessors[idx].processorAssembly.StopAssembly();
                    try
                    {
                        System.AppDomain.Unload(fAppProcessors[idx].domain);
                    }
                    catch (Exception)
                    {

                    }
                    Thread.Sleep(1000);
                    fAppProcessors[idx].domain = null;
                    fAppProcessors[idx] = null;
                    fAppProcessors.RemoveAt(idx);
                    System.GC.Collect();
                }
            }
        }
...


MyAppProcessor
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
    public class MyAppProcessor
    {
        public AppDomain domain {get;set;}
        public MyProcessorAssembly processorAssembly { get; set; }
        public string AppProcessorName { get; set; }

        public short ID
        {
            get
            {
                return processorAssembly.ID;
            }
        }

        public string ProcessorClassName
        {
            get
            {
                return processorAssembly.ClassName;
            }
        }
    }

MyProcessorAssembly
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
    public class MyProcessorAssembly : MarshalByRefObject
    {
        private Assembly fAssembly;
        private System.Type fType = null;
        private MyProcessor processor = null;
        private short fID = 0;
        private string fClassName = "";
 
        public override object InitializeLifetimeService()
        {
            return null;
        }

        public bool LoadAssembly(MyProcessorConfig aConf)
        {
            if (aConf == null) return false;
            return LoadAssembly(aConf.ID,  aConf.LibraryPath, aConf.ProcessorClassName);
        }

        public bool LoadAssembly(short anID, string aLibraryPath, string aClassName)
        {
            try
            {
                fAssembly = Assembly.Load(AssemblyName.GetAssemblyName(aLibraryPath));
            }catch(Exception ex){
                Logger.Log("Невозможно загрузить сборку для" + aClassName, ex);
                return false;
            }

            if (fAssembly == null)
            {
                Logger.Log("Сборка " + aLibraryPath + " не загружена...");
                return false;
            }

            try
            {
                fType = fAssembly.GetType(aClassName);
            }
            catch (Exception ex1)
            {
                Logger.Log("Невозможно получить тип для" + aClassName, ex1);
                return false;
            }


            if (!fType.BaseType.Name.Equals("MyProcessor"))
            {
                Logger.Log("Указанный класс '" + aClassName + "' не является наследником от MyProcessor",System.Diagnostics.EventLogEntryType.Error);
                return false;
            }

            fID = anID;
            fClassName = aClassName;

            processor = (MyProcessor)fAssembly.CreateInstance(fType.FullName);
            processor.ID = anID;
            processor.InitProcessor();

            return true;
        }

...
        public short ID
        {
            get { return fID; }
        }

        public string ClassName
        {
            get { return fClassName; }
        }

...

        public void StopAssembly()
        {
            if (processor == null) throw new InvalidOperationException("My Processor класс не указан.");
            processor.StopProcessor();
        }
    }


MyProcessor - и есть тот абстрактный класс на основании которого созданы последующие обработчики, которые реализуют соответствующую бизнес логику.


netivan...Каждый плагин в домене это перебор ) Не думаю. Представьте себе ситуацию, когда сторонняя библиотека роняет сервис и Вам звонят клиенты у которых "денюшки" пропали... потому что по причине криворукости программистов компании А, свалился сервис в который была подгружена библиотека от компании Б...
...
Рейтинг: 0 / 0
TCP\SSL-Server на C#
    #38469838
JustOxlamon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Alex Kuznetsov,

Огромное спасибо, я покопаю в ту сторону, конечно из-за реалтаймовского характера приложения, смущает проблема скорости.
Вы обошлись тут без интерфейсов, у нас тоже базовый абстрактный класс. По-моему это супер.
...
Рейтинг: 0 / 0
TCP\SSL-Server на C#
    #38469864
Alex Kuznetsov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
JustOxlamonAlex Kuznetsov,

Огромное спасибо, я покопаю в ту сторону, конечно из-за реалтаймовского характера приложения, смущает проблема скорости.
Вы обошлись тут без интерфейсов, у нас тоже базовый абстрактный класс. По-моему это супер.
А что скорость - она от скорости обработки запроса зависит...
У меня под тестовой нагрузкой сервис за одну секунду обрабатывал до 512 сообщений, а это, принятие + парсинг + уложить в базу + обработать + отослать ответ + уложить ответ в базу...
И это при том, что всё крутилось в виртуалке с ХР, с установленной в ней студией, SQL сервером, запущенным IIS, сервис был с отладочной инфой, трейсингом и т.д., памяти было выделено под виртуалку всего 3 гига... пакеты шли пачкой по 512 сообщений.
...
Рейтинг: 0 / 0
TCP\SSL-Server на C#
    #38469934
netivan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alex KuznetsovJustOxlamonAlex Kuznetsov,

Огромное спасибо, я покопаю в ту сторону, конечно из-за реалтаймовского характера приложения, смущает проблема скорости.
Вы обошлись тут без интерфейсов, у нас тоже базовый абстрактный класс. По-моему это супер.
А что скорость - она от скорости обработки запроса зависит...
У меня под тестовой нагрузкой сервис за одну секунду обрабатывал до 512 сообщений, а это, принятие + парсинг + уложить в базу + обработать + отослать ответ + уложить ответ в базу...
И это при том, что всё крутилось в виртуалке с ХР, с установленной в ней студией, SQL сервером, запущенным IIS, сервис был с отладочной инфой, трейсингом и т.д., памяти было выделено под виртуалку всего 3 гига... пакеты шли пачкой по 512 сообщений.
512 в секнду в записью в базу? Да вы монстр. По поводу доменов наверное согласен, если считать что плагины пишет другой человек, то да.
...
Рейтинг: 0 / 0
TCP\SSL-Server на C#
    #38470023
Alex Kuznetsov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
netivan512 в секнду в записью в базу? Да вы монстр... Ну почему сразу монстр? Обычная очередь, плюс поток, плюс пулл соединений... Всё нормально...
В данном случае задача сервиса была дать как можно быстрый ответ SMPP серверу о том, что пакет получен,
распарсен и принят в обработку, а когда оно именно в базу попадёт - это уже вопрос отдельный
...
Рейтинг: 0 / 0
TCP\SSL-Server на C#
    #38470047
netivan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alex Kuznetsovnetivan512 в секнду в записью в базу? Да вы монстр... Ну почему сразу монстр? Обычная очередь, плюс поток, плюс пулл соединений... Всё нормально...
В данном случае задача сервиса была дать как можно быстрый ответ SMPP серверу о том, что пакет получен,
распарсен и принят в обработку, а когда оно именно в базу попадёт - это уже вопрос отдельный
очередь, так и писали бы : отправилась "задача" на запись в базу :)
...
Рейтинг: 0 / 0
TCP\SSL-Server на C#
    #38470057
Alex Kuznetsov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
netivan...
очередь, так и писали бы : отправилась "задача" на запись в базу :) Ну можно и так сказать...
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
TCP\SSL-Server на C#
    #38812717
Фотография des1roer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
народ подскажите в чем трабла
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
   internal class DoWork
        {
            string SERV, MES, ParseGlob;
            private bool doWork;
            private System.Threading.Thread thread;
            readonly EventWaitHandle wh = new AutoResetEvent(false);
            int IdCom, Port, ansLen;
            Regex rxNums = new Regex(@"^\d+$");

            internal DoWork(String server, String message, Int32 port, Int32 idcom, String Parse, Int32 dlina)
            {
                SERV = server;
                MES = message;
                Port = port;
                IdCom = idcom;
                ansLen = dlina;
                if (Parse != "")
                    ParseGlob = Parse;
            }
            public void ThreadStart()
            {
                doWork = true;
                thread = new Thread(Execute);
                thread.Start();


            }
            public void ThreadStop()
            {
                doWork = false;
                wh.Set();

            }
            void Execute()
            {
                try
                {
                    if (doWork)
                        Connect(SERV, MES, Port);

                }
                catch (Exception msg)
                {
                    logger.Trace("Execute() " + msg);
                    return;
                }
            }

            public void Connect(String server, String message, Int32 port)
            {
                try
                {
                    // Create a TcpClient.
                    // Note, for this client to work you need to have a TcpServer 
                    // connected to the same address as specified by the server, port
                    // combination.

                    // 
                    TcpClient client = new TcpClient(server, port);

                    // Translate the passed message into ASCII and store it as a Byte array.
                    Byte[] data = System.Text.Encoding.ASCII.GetBytes(message);

                    // Get a client stream for reading and writing.
                    //  Stream stream = client.GetStream();

                    NetworkStream stream = client.GetStream();

                    // Send the message to the connected TcpServer. 
                    stream.Write(data, 0, data.Length);

                    //   logger.Trace("Sent: {0}", message);
                    if (list[10] == "1")
                    {
                        logger.Trace("Sent: {0}", message);
                    }
                    doWork = false;
                    // Receive the TcpServer.response.
                    //  Thread.Sleep(2000);   
                    // Buffer to store the response bytes.
                    data = new Byte[256];

                    // String to store the response ASCII representation.
                    String responseData = String.Empty;

                    // Read the first batch of the TcpServer response bytes.
                    Int32 bytes = stream.Read(data, 0, data.Length);
                    responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);

                    if (list[10] == "1")
                    {
                        logger.Trace("port_DataReceived " + responseData);
                    }


                }
                catch (ArgumentNullException e)
                {
                    logger.Trace("ArgumentNullException: {0}", e);
                    return;
                }
                catch (SocketException e)
                {
                    logger.Trace("SocketException: {0}", e);
                    Thread.Sleep(1000); 
                    return;
                }
            }
            public bool ThreadState()
            {
                if (doWork)
                    return true;
                else return false;
            }
        }


опрашивает первые 3 раза (на одном порту 4 прибора у них разные коды) а потом пишет Trace|SocketException: {0}
...
Рейтинг: 0 / 0
TCP\SSL-Server на C#
    #38812747
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
а кто будет делать NetworkStream.Dispose и TcpClient.Close ??
...
Рейтинг: 0 / 0
TCP\SSL-Server на C#
    #38812749
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
des1roer
Код: c#
1.
2.
3.
4.
5.
6.
public bool ThreadState()
            {
                if (doWork)
                    return true;
                else return false;
            }


Вот это шедевр.

public bool ThreadState { get { return doWork; } }
...
Рейтинг: 0 / 0
TCP\SSL-Server на C#
    #38812759
Arm79
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
des1roer
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
            public void ThreadStart()
            {
                doWork = true;
                thread = new Thread(Execute);
                thread.Start();


            }
            public void ThreadStop()
            {
                doWork = false;
                wh.Set();

            }


Так делать можно, но не нужно, из старого кода:
отдельный тред
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
using System;
using System.Threading;

namespace Threads
{
    /// <summary>
    /// Аргументы для события "Старт потока"
    /// </summary>
    public sealed class StartArgs : EventArgs
    {
        #region .ctor

        public StartArgs(bool wasStarted)
        {
            WasStopped = wasStarted;
        }

        #endregion

        /// <summary>
        /// Состояние потока до вызова метода Start()
        /// </summary>
        public bool WasStopped { get; private set; }
    }

    /// <summary>
    /// Аргументы для события "Останов потока"
    /// </summary>
    public sealed class StopArgs : EventArgs
    {
        #region .ctor

        public StopArgs(bool wasStarted, bool exitByTimeout)
        {
            WasStarted = wasStarted;
            IsExitByTimeout = exitByTimeout;
        }

        #endregion

        /// <summary>
        /// Состояние потока до вызова метода Stop()
        /// </summary>
        public bool WasStarted { get; private set; }

        /// <summary>
        /// Флаг прерывания потока исполнения по таймауту
        /// </summary>
        public bool IsExitByTimeout { get; private set; }
    }

    /// <summary>
    /// Шаблон для выполнения метода в отдельном потоке с дополнительным функционалом управления и мониторинга
    /// </summary>
    /// <remarks>Потомки должны быть сериализуемыми</remarks>
    public abstract class ThreadWorkerTemplate : DisposableTemplate
    {
        #region Private

        private int _threadFlag;
        private readonly Thread _thread;

        /// <summary>
        /// Обработчик потока
        /// </summary>
        private void ThreadHandler()
        {
            // Здесь реализуем пользовательскую задержку, вместо Thread.Sleep(), так как она позволит отреагировать на команду завершения работы
            DateTime lastExecuted = DateTime.MinValue;
            Func<bool> isAllowed =
                () =>
                {
                    DateTime now = DateTime.Now;
                    bool result = IsNothingDelay() || IsDelaySpended(now, lastExecuted);

                    if (result)
                        lastExecuted = now;

                    // Допустим и 0, то тогда в диспетчере будет показываться 100% загрузка. При этом приложение будет отзываться
                    // Значение 1 задает на самом деле интервал 10-15, то есть менее минимального квантификатора задержки быть не может
                    if (IterationTimespan != -1)
                        Thread.Sleep(1);

                    return result;
                };

            // в цикле осуществляется вызов бизнес-функции 
            while (Interlocked.CompareExchange(ref _threadFlag, 0, 0) == 1)
            {
                if (isAllowed())
                    WorkFunction();
            }
        }

        /// <summary>
        /// Проверка, прошел ли минимальный интервал времени между итерациями
        /// </summary>
        /// <param name="now"></param>
        /// <param name="lastExecuted"></param>
        /// <returns></returns>
        /// <remarks>задержка не менее заданного интервала времени</remarks>
        private bool IsDelaySpended(DateTime now, DateTime lastExecuted)
        {
            return (now > lastExecuted) // учет коррекции времени ntp-сервисом
                   &&
                   (now - lastExecuted).TotalMilliseconds > IterationTimespan;
        }

        /// <summary>
        /// Проверка на наличие задержки
        /// </summary>
        /// <remarks>-1 означает отсутствие какой-либо задержки</remarks>
        private bool IsNothingDelay()
        {
            return IterationTimespan == -1;
        }

        #endregion

        #region .ctor/dispose/finalize

        protected ThreadWorkerTemplate(int timeout) : this(timeout, new TimeSpan(0, 0, 0, 10)) { }

        protected ThreadWorkerTemplate(int timeout, TimeSpan joinTimeout, ApartmentState apartmentState = ApartmentState.Unknown)
        {
            IterationTimespan = timeout;
            JoinTimeout = joinTimeout;

            _threadFlag = 0;
            _thread = new Thread(ThreadHandler);
            _thread.SetApartmentState(apartmentState);
        }

        #endregion

        #region Invocators

        private void InvokeOnStart(StartArgs e)
        {
            EventHandler<StartArgs> handler = OnStart;
            if (handler != null) handler(this, e);
        }

        private void InvokeOnStop(StopArgs e)
        {
            EventHandler<StopArgs> handler = OnStop;
            if (handler != null) handler(this, e);
        }

        #endregion

        #region Events

        /// <summary>
        /// Событие, возникающее при старте обработки метода
        /// </summary>
        public event EventHandler<StartArgs> OnStart;

        /// <summary>
        /// Событие, возникающее при останове обработки метода
        /// </summary>
        public event EventHandler<StopArgs> OnStop;

        #endregion

        #region Management

        /// <summary>
        /// Старт запуска метода в отдельном потоке
        /// </summary>
        public void Start()
        {
            bool oldState = !IsStarted;

            // стартуем с одновременным измененем флага
            if (Interlocked.CompareExchange(ref _threadFlag, 1, 0) == 0)
                _thread.Start();

            InvokeOnStart(new StartArgs(oldState));
        }

        /// <summary>
        /// Останов обработки метода в отдельном потоке
        /// </summary>
        public void Stop()
        {
            bool oldState = IsStarted;
            bool exitByTimeout = false;

            // стопаем с одновременным измененем флага
            if (Interlocked.CompareExchange(ref _threadFlag, 0, 1) == 1)
                exitByTimeout = !_thread.Join(JoinTimeout);

            InvokeOnStop(new StopArgs(oldState, exitByTimeout));
        }

        #endregion

        #region For overrite

        /// <summary>
        /// Метод, который должен исполняться в отдельном потоке.
        /// </summary>
        protected abstract void WorkFunction();

        #endregion

        #region Properties

        /// <summary>
        /// Флаг, показывающий текущее состояние ThreadWorker (запущен или нет)
        /// </summary>
        public bool IsStarted
        {
            get { return Interlocked.CompareExchange(ref _threadFlag, 0, 0) == 1; }
        }

        /// <summary>
        /// Интервал времени, после которого прекращается номмальное завершение потока испольнения метода <see cref="WorkFunction"/>
        /// </summary>
        public TimeSpan JoinTimeout { get; private set; }

        /// <summary>
        /// Минимальный интервал времени между вызовами метода <see cref="WorkFunction"/>
        /// </summary>
        public int IterationTimespan { get; private set; }

        #endregion
    }
}

...
Рейтинг: 0 / 0
22 сообщений из 47, страница 2 из 2
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / TCP\SSL-Server на C#
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]