Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.71/7: Рейтинг темы: голосов - 7, средняя оценка - 4.71
0 / 0 / 0
Регистрация: 22.02.2022
Сообщений: 27

Многопоточный асинхронный сервер

30.08.2022, 11:42. Показов 1607. Ответов 17
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Друзья, прошу помощи в написании многопоточного асинхронного сервера, операции которого основаны на async/await, а не на callback'ах. Подскажите как подступиться, не пойму логику хождения и взаимодействия потоков. Нужно ли столько-то потоков из пула потоков выделать заранее под работу с клиентом? Заранее благодарен за помощь

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
namespace serverChat
{
    public class Server
    {
        private Socket _server;
        private int port=8003;
        private EndPoint EndPoint;
        private int counter;
 
        public int CounterClient 
        { 
            get {return counter;} 
            set
            {
                counter=value;
            } 
        
        }
 
        private byte[] buffer;
        public byte[] Buffer
        {
            get {return buffer;}
            set
            {
                buffer=value;
            }
        }
 
 
 
        public Server()
        {
            _server=new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
            EndPoint=new IPEndPoint(IPAddress.Parse("127.0.0.1"),port);
        }
 
        public async Task Start()
        {
            Buffer=new byte[20];
            _server.Bind(EndPoint);
            _server.Listen(10);
            while(true){
            {
                var client=await _server.AcceptAsync();
                Console.WriteLine($"клиент с айпи и портом:{(IPEndPoint)client.RemoteEndPoint} подключился");
                //client.ReceiveAsync()    
            }
            }        
        }
 
        public void Close()
        {
            _server.Close();
        }
 
        private string Decoding(byte[] bytes)
        {
            return Encoding.Unicode.GetString(bytes);
        }
   
    }
}
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
30.08.2022, 11:42
Ответы с готовыми решениями:

Асинхронный и многопоточный - одно и то же?
асинхронный и многопоточный - одно и то же?

Многопоточный сервер
Есть код консольного клиента using System; using System.Collections.Generic; using System.Text; using System.Net.Sockets; ...

Синхронный многопоточный сервер
Здравствуйте. В синхронном многопоточном сервере для каждого соединения сокета создается отдельный поток. В этих потоках происходит прием,...

17
 Аватар для IamRain
4694 / 2702 / 734
Регистрация: 02.08.2011
Сообщений: 7,233
30.08.2022, 13:01
Цитата Сообщение от Ivanopola Посмотреть сообщение
Нужно ли столько-то потоков из пула потоков выделать заранее под работу с клиентом?
Нет, ничего не нужно.
Обычно выделяют один поток на прослушку входящих подключений. И каждый вновь подключенный клиент работает в отдельном потоке (запущенном через Task.Run).
Для начала так и сделайте.
Это если вкратце, если более сложно, то дополнительно можно еще абстрагировать модели диспетчерезации (прием входящих подключений). Например выделить 3 потока на прослушку входящих подключений, остальное - аналогично.

Добавлено через 44 секунды
Но судя по коду, пока вам это точно не нужно.
0
0 / 0 / 0
Регистрация: 22.02.2022
Сообщений: 27
30.08.2022, 13:13  [ТС]
IamRain, тут разве не может всплыть проблема, что не хватит рабочих потоков под каждого клиента? если дать каждому клиенту по потоку, то зачем вообще асинхронные функции сокетов? ну работает и работает каждый подключенный клиент в своём потоке!
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
30.08.2022, 13:23
Цитата Сообщение от Ivanopola Посмотреть сообщение
тут разве не может всплыть проблема, что не хватит рабочих потоков под каждого клиента?
Может, если клиентов много и обработка запроса — длительные вычисления на процессоре.
Если того и другого нет, то количество потоков не имеет значения.
0
 Аватар для IamRain
4694 / 2702 / 734
Регистрация: 02.08.2011
Сообщений: 7,233
30.08.2022, 13:41
Цитата Сообщение от Ivanopola Посмотреть сообщение
IamRain, тут разве не может всплыть проблема,
У метода Listen есть параметр Backlog - тут можно указать максимальное число подключений, которые будут приняты.
Цитата Сообщение от Ivanopola Посмотреть сообщение
то зачем вообще асинхронные функции сокетов?
Если клиентов слишком много, то асинхронная их обработка точно не справится - в любом случае это запрос большого кол-ва ресурсов, соответственно эти ресурсы надо выделять.
Выделение большого количества потоков не должно быть проблемой, если подключения не предполагают длительную работу (сутками).

Добавлено через 1 минуту
Как я понял ,вам пока еще рано думать о производительности.
0
7 / 7 / 5
Регистрация: 25.03.2018
Сообщений: 377
30.08.2022, 13:42
IamRain, а если общие переменные фигурируют, то просто локом обойтись?
0
 Аватар для IamRain
4694 / 2702 / 734
Регистрация: 02.08.2011
Сообщений: 7,233
30.08.2022, 13:45
cinekst_207, это уже другой вопрос, непонятно зачем он тут задан.
0
7 / 7 / 5
Регистрация: 25.03.2018
Сообщений: 377
30.08.2022, 13:51
IamRain, хотите сказать такой надобности не возникает в коммерческой разработке?) А задан потому, что эти темы пересекаются, что за духота-то =/
0
0 / 0 / 0
Регистрация: 22.02.2022
Сообщений: 27
30.08.2022, 13:56  [ТС]
ребята, какие-то рекомендации можно? вы на мой вопрос так и не ответили.
"Если дать каждому клиенту по потоку, то зачем вообще асинхронные функции сокетов? ну работает и работает каждый подключенный клиент в своём потоке!"
0
7 / 7 / 5
Регистрация: 25.03.2018
Сообщений: 377
30.08.2022, 14:00
Ivanopola, чтобы на время подключения не задерживать поток. Например у вас идёт подключение и есть интерфейс, который не будет ни на что откликаться пока у Вас идёт подключение. А с асинхронностью на время подключения Ваш интерфейс будет работать. Асинхронность регулирует ресурсы в потоке, в то время как многопоточность - потоки
0
0 / 0 / 0
Регистрация: 22.02.2022
Сообщений: 27
30.08.2022, 14:02  [ТС]
cinekst_207, так тут человек выше говорит, что следует выделить один поток под прослушку и каждому клиенту вешать поток, тогда какой толк?
0
7 / 7 / 5
Регистрация: 25.03.2018
Сообщений: 377
30.08.2022, 14:10
Ivanopola, зависит от того, для чего Вам нужно подключение. Если это подключение будет временным и буквально занимает долю секунды, то смысла выделять под него поток особого нет. А вообще, имелось ввиду что-то подобное
1. Асинхронное подключение (чтобы можно было взаимодействовать с другими элементами программы на время подключения)
2. Выделили поток
3. Асихнронная обработка (чтобы при надобности в ресурсах, выделенный поток ушёл работать там, где это нужно и потом вернулся бы обратно к обработке)
4. Конец
Грубо говоря, асинхронность говорит потоку следующее: я начну подключение, а пока ты подключаешься, я пойду займусь другими более важными делами, где нужна моя помощь.
Как-то так.

Добавлено через 1 минуту
Ivanopola, не забывайте, что поток, который Вы выделили для клиента, может выполнять кучу другой полезной работы. Асинхронность как раз для этого и нужна, чтобы на время длительных операций поток занимался чем-нибудь другим.
0
0 / 0 / 0
Регистрация: 22.02.2022
Сообщений: 27
30.08.2022, 14:20  [ТС]
cinekst_207, не могу понять.
C#
1
2
3
4
while(true)
{
       var client=await _server.AcceptAsync();  
}
Я тут получается асинхронно асепчу клиентский сокет, основной поток возвращается в метод, который его вызвал (Main) в моём случае. Дальше метод будет работать "в продолжении" в другом потоке, и по итогу в отладке, здесь один поток начинается крутить до бесконечности цикл, после того как основной поток сразу "ушёл".
0
 Аватар для IamRain
4694 / 2702 / 734
Регистрация: 02.08.2011
Сообщений: 7,233
30.08.2022, 14:46
Цитата Сообщение от Ivanopola Посмотреть сообщение
и по итогу в отладке, здесь один поток начинается крутить до бесконечности цикл,
Возможно, а может после await это уже будет другой поток. Надо смотреть в отладке.

Даже Task.Yield() который никогда не выполняется синхронно, то есть он освобождает текущий поток, то в цикле вида:
C#
1
2
3
4
5
while (true)
{
    Console.WriteLine($"Thread: {Thread.CurrentThread.ManagedThreadId}");
    await Task.Yield();
}
Изредка, но будет выдавать одинаковые Id-потоков.
Хотя не факт, что это синхронное выполнение, может просто планировщик взял тот же поток для continuation, что был и на предыдущей итерации.
Вообщем, надо смотреть, как там под капотом реализовано, может есть какая-то оптимизация, имхо. И для AcceptAsync в том числе.
0
0 / 0 / 0
Регистрация: 22.02.2022
Сообщений: 27
30.08.2022, 16:14  [ТС]
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
        public async Task Start()
        {
            Buffer=new byte[20];
            _server.Bind(EndPoint);
            _server.Listen(10);
                while(true){
                {
                    var client=await _server.AcceptAsync();
                    Task.Run(()=>ClientReceive(client));
                }
            }        
        }
 
        private void ClientReceive(Socket client)
        {
            Console.WriteLine($"клиент с айпи и портом:{(IPEndPoint)client.RemoteEndPoint} подключился");
            while(true){
            byte[] buffer=new byte[30];
            client.Receive(buffer,0,buffer.Length,SocketFlags.None);
            Console.WriteLine(Encoding.Default.GetString(buffer));
            }
        }
UPD: IamRain, говорю же глянул после await, когда основной поток покинул метод, остаётся один поток который крутит бесконечный цикл while.

Добавлено через 41 минуту
как только дошло дело до кода, все оставили меня, ЭХХХХХХХХ
0
 Аватар для IamRain
4694 / 2702 / 734
Регистрация: 02.08.2011
Сообщений: 7,233
30.08.2022, 16:17
Ivanopola, вроде на все ваши вопросы ответили, не? Что еще непонятно?
0
0 / 0 / 0
Регистрация: 22.02.2022
Сообщений: 27
30.08.2022, 16:20  [ТС]
IamRain, зачем теперь в методе ClientReceive прибегать к асинхронный методам(AsyncSend, AsyncReceive), не подскажите?
0
 Аватар для IamRain
4694 / 2702 / 734
Регистрация: 02.08.2011
Сообщений: 7,233
30.08.2022, 16:33
Можно и не прибегать, однако обычно принято весь код делать асинхронным, от начала и до конца.
В вашем случае, если метод будет использовать дальше async-методы, то надо бы его сделать async Task, а не async void.
Связано это с тем что async void не await- ятся, и с пробросом возникших исключений вверх по стеку.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
30.08.2022, 16:33
Помогаю со студенческими работами здесь

Многопоточный клиент сервер c дуплексом
Добрый день, не знаю как реализовать многопоточный клиент сервер с дуплексом и синхронной отправкой и получением данных как будто это...

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

асинхронный сервер
Не могу определить выполняется ли метод в отдельном потоке имеется код public ClientConnection(Socket AcceptedSocket) ...

Асинхронный сервер
Интересует такая тема: Мне нужно реализовать сервер на C#, который будет получать запрос от клиента(json), а после этого будет проводить...

Графический чат через многопоточный сервер
Есть многопоточный сервер и клиент, который может общаться сам с собой) Помогите сделать чат так, чтобы несколько клиентов могли общаться...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
Новые блоги и статьи
Midnight Chicago Blues
kumehtar 24.03.2026
Такой Midnight Chicago Blues, знаешь?. . Когда вечерние улицы становятся ночными, а ты не можешь уснуть. Ты идёшь в любимый старый бар, и бармен наливает тебе виски. Ты смотришь на пролетающие. . .
Контроль уникальности заводского номера - вариант №2
Maks 24.03.2026
В отличие от предыдущего варианта добавлено прерывание циклов, также добавлены новые переменные для сохранения контекста ошибки перед прерыванием цикла: Процедура ПередЗаписью(Отказ, РежимЗаписи,. . .
SDL3 для Desktop (MinGW): Вывод текста со шрифтом TTF с помощью библиотеки SDL3_ttf на Си и C++
8Observer8 24.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-text-sdl3-c. zip finish-text-sdl3-cpp. zip
Жизнь в неопределённости
kumehtar 23.03.2026
Жизнь — это постоянное существование в неопределённости. Например, даже если у тебя есть список дел, невозможно дойти до точки, где всё окончательно завершено и больше ничего не осталось. В принципе,. . .
Модель здравоСохранения: работники работают быстрее после её введения.
anaschu 23.03.2026
geJalZw1fLo Корпорация до введения программа здравоохранения имела много невыполненных работниками заданий, после введения программы количество заданий выросло. Но на выплатах по больничным это. . .
Контроль уникальности заводского номера - вариант №1
Maks 23.03.2026
Алгоритм контроля уникальности заводского (или серийного) номера на примере документа выдачи шин для спецтехники с табличной частью в КА2. Данные берутся из регистра сведений, по которому настроено. . .
Хочу заставить корпорации вкладываться в здоровье сотрудников: делаю мат модель здравосохранения
anaschu 22.03.2026
e7EYtONaj8Y Z4Tv2zpXVVo https:/ / github. com/ shumilovas/ med2. git
Программный отбор элементов справочника по группе
Maks 22.03.2026
Установка программного отбора элементов справочника "Номенклатура" из модуля формы документа в КА2. В качестве фильтра для отбора справочника служит группа номенклатуры. Отбор по наименованию. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru