Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.73/11: Рейтинг темы: голосов - 11, средняя оценка - 4.73
17 / 5 / 3
Регистрация: 22.03.2011
Сообщений: 329

Асинхронный клиент, цикличная отправка данных

08.03.2013, 13:15. Показов 2432. Ответов 9
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Приветики xD В общем, раньше я только брал готовые сервера и клиенты и че-то в них изменял не понимая, как они работают на самом деле. Но теперь! Я решил обмазаться этими знаниями с ног до головы! Решил написать асинхронный клиент, пока что только с функцией отправки. Нужно, чтобы отправка была цикличной, например, вызвали метод для отправки сообщения, оно отправилось и мы снова вызываем метод для отправки сообщения. Сообщения вводятся ручками в консольку. Я, конечно, понимаю, что можно сделать вечный цикл и в нем запрашивать ввод данных и после этого отправлять их, но если нужно будет еще и принимать данные?? я же не смогу сделать два вечных цикла. Ну я подумал, если в завершающем отправку методе мы будет вызывать метод, который начинает отправку, то все будет чики-пуки. Но не тут то было. Первый раз отправляется нормально, как не странно. Но второй раз, при вводе данных, они не отправляются, а приложение закрывается. Значит срабатывает
C#
1
Console.Read()
в мэйне.
Как зациклить отправку сообщений без вечного цикла??? Спасибки.
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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Net;
using System.Net.Sockets;
using System.Threading;
 
namespace клиент_типа
{
    class Program
    {
        private static byte[] buff = new byte[1024];
        private static Socket sock;
 
        static void Main(string[] args)
        {
            Socket forConn = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            forConn.BeginConnect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9095), new AsyncCallback(EndConnection), forConn);
           
                string s = Console.ReadLine();
                forConn.BeginSend(Encoding.UTF8.GetBytes(s), 0, Encoding.UTF8.GetByteCount(s), 0, new AsyncCallback(EndSending), forConn);
 
 
                Console.Read();
        }
        private static void EndConnection(IAsyncResult ar)
        {
            try
            {
                sock = (Socket)ar.AsyncState;
                sock.EndConnect(ar);
                Console.WriteLine("Патключилися");
            }
            catch (SocketException ex)
            {
                Console.WriteLine(ex.Message);
            }
        }
       
        private static void EndSending(IAsyncResult ar)
        {
            Socket sck = (Socket)ar.AsyncState;
            int i = sck.EndSend(ar);
            Console.WriteLine("послали "+i+" байт");
            string s = Console.ReadLine();
            sck.BeginSend(Encoding.UTF8.GetBytes(s), 0, Encoding.UTF8.GetByteCount(s), 0, new AsyncCallback(EndSending), sck);
        }
    }
}
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
08.03.2013, 13:15
Ответы с готовыми решениями:

Асинхронный клиент-сервер
Здравствуйте. Вот уже 3 дня бьюсь над проблемой, решение которой не могу найти. Вообщем, коротко говоря, имеется серверное приложение,...

Асинхронный клиент с использованием Callback
Приветики. В общем я давно не занимался клиенто-серверными делами. И вот решил запилить клиент к серверу основаный на вызове методов...

Асинхронный клиент сервер
Здравствуйте, как сделать асинхронный клийент сервер? что бы сервер мог одновременно всем клиентам отправлять данные (для игры)

9
 Аватар для IamRain
4694 / 2702 / 734
Регистрация: 02.08.2011
Сообщений: 7,228
08.03.2013, 14:29
Код выполняется последовательно - в Main, поскольку у вас асинхронный клиент, сразу после строчки forConn.BeginSend(...) , пойдет метод Console.Read(), а не тот,что находится в EndSending, и при вводе строки приложение закроется.
Думаю, если убрать в Main Console.Read(), то приложение закроется сразу после отправки. проверьте. Думаю, нужен все-таки бесконечный цикл.
".NET Сетевое программирование для профессионалов" - там есть пример двойного вечного цикла ( стр.116,правда, это сервер) - внешний для постоянной прослушки, внутренний - для приема. (из него выход через break по условию).
0
17 / 5 / 3
Регистрация: 22.03.2011
Сообщений: 329
08.03.2013, 15:00  [ТС]
Цитата Сообщение от IamRain Посмотреть сообщение
Код выполняется последовательно - в Main, поскольку у вас асинхронный клиент, сразу после строчки forConn.BeginSend(...) , пойдет метод Console.Read(), а не тот,что находится в EndSending, и при вводе строки приложение закроется.
Думаю, если убрать в Main Console.Read(), то приложение закроется сразу после отправки. проверьте. Думаю, нужен все-таки бесконечный цикл.
".NET Сетевое программирование для профессионалов" - там есть пример двойного вечного цикла ( стр.116,правда, это сервер) - внешний для постоянной прослушки, внутренний - для приема. (из него выход через break по условию).
так этот сервер синхронный же. Если пришло сообщение - принимаем, приняли? break и снова ждем сообщения. А как же это запилить с асинхронным клиентом? Будь считывание с консоли во внешнем или во внутреннем цикле, все-равно, пока я не введу сообщение - принятие данных будет невозможным =\
0
 Аватар для IamRain
4694 / 2702 / 734
Регистрация: 02.08.2011
Сообщений: 7,228
08.03.2013, 15:10
В консольном приложении вы не почувствуете разницу между синхронным и асинхронным клиентами.
Асинхронные методы, насколько я знаю, выполняются автоматически в другом потоке, чтобы текущий поток смог выполнять какие-то свои действия. (Например, отображать интерфейс)
+ к тому, раз уж вы используете асинхронную модель, нужно вручную синхронизировать действия:
1. Вызов Socket.Send строго после Socket.Connect
2. Вызов Socket.Receve строго после Socket.Send
ну и на серверной стороне то же.
0
17 / 5 / 3
Регистрация: 22.03.2011
Сообщений: 329
08.03.2013, 15:29  [ТС]
Цитата Сообщение от IamRain Посмотреть сообщение
В консольном приложении вы не почувствуете разницу между синхронным и асинхронным клиентами.
Асинхронные методы, насколько я знаю, выполняются автоматически в другом потоке, чтобы текущий поток смог выполнять какие-то свои действия. (Например, отображать интерфейс)
+ к тому, раз уж вы используете асинхронную модель, нужно вручную синхронизировать действия:
1. Вызов Socket.Send строго после Socket.Connect
2. Вызов Socket.Receve строго после Socket.Send
ну и на серверной стороне то же.
дык мне не для консольного приложения надо. и что значит - не почувствую разницу. Если у меня 2 клиента только что подключились к серверу, а сервер просто отсылает 1 сообщение от 1 клиента всем другим клиентам. То если будет так:
1. Вызов Socket.Send строго после Socket.Connect
2. Вызов Socket.Receve строго после Socket.Send

И 1 клиент отошлет сообщение, а другие клиенты не, то другие клиенты не смогут получить сообщение от первого клиента. Не порядок.
0
 Аватар для IamRain
4694 / 2702 / 734
Регистрация: 02.08.2011
Сообщений: 7,228
08.03.2013, 15:39
Цитата Сообщение от lawliet93 Посмотреть сообщение
Вызов Socket.Receve строго после Socket.Send
Я имел ввиду тот случай, если сервер сразу же отвечает тому же клиенту.
Ну а вообще, тогда шлем сообщения всем сокетам, с которыми установлены соединения, кроме отправителя.
В любом случае, ввод данных в бесконечном цикле. + Можно еще групповую рассылку посмотреть.(тогда выделенный сервер можно вообще убрать)
0
17 / 5 / 3
Регистрация: 22.03.2011
Сообщений: 329
08.03.2013, 15:43  [ТС]
Цитата Сообщение от IamRain Посмотреть сообщение
Я имел ввиду тот случай, если сервер сразу же отвечает тому же клиенту.
Ну а вообще, тогда шлем сообщения всем сокетам, с которыми установлены соединения, кроме отправителя.
В любом случае, ввод данных в бесконечном цикле. + Можно еще групповую рассылку посмотреть.(тогда выделенный сервер можно вообще убрать)
дык с сервером у меня проблем нет. у меня с клиентом проблемы, сервер принимает сообщения, че-то делает с ними и отправляет обратно. в нем нету вызова блокирующих поток. а в клиенте есть Console.ReadLine(); И групповая рассылка не пойдет. я ж делаю сервер для игры многопользовательской, а там нужна работа с БД
0
 Аватар для IamRain
4694 / 2702 / 734
Регистрация: 02.08.2011
Сообщений: 7,228
08.03.2013, 16:03
C#
1
2
3
4
5
6
7
8
9
10
11
  static void Main(string[] args)
        {
            Socket forConn = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            forConn.BeginConnect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9095), new AsyncCallback(EndConnection), forConn);
           
                string s = Console.ReadLine();
                forConn.BeginSend(Encoding.UTF8.GetBytes(s), 0, Encoding.UTF8.GetByteCount(s), 0, new AsyncCallback(EndSending), forConn);
 
 
                Console.Read();
        }
Вечного цикла нет,а поток Main-a главный, - значит он сразу завершает работу после Console.ReadLine ,а если в приложении один главный поток, и неважно какое число фоновых, то все они тоже завершают работу. Так что повторный вызов BeginConnect из callback метода не будет работать.

Добавлено через 6 минут
Вот это должно помочь. Всего лишь то, что нужно было сделать.
C#
1
2
3
4
5
while(true)
{
 string s = Console.ReadLine();
                forConn.BeginSend(Encoding.UTF8.GetBytes(s), 0, Encoding.UTF8.GetByteCount(s), 0, new AsyncCallback(EndSending), forConn);
}
0
17 / 5 / 3
Регистрация: 22.03.2011
Сообщений: 329
08.03.2013, 16:19  [ТС]
Цитата Сообщение от IamRain Посмотреть сообщение
C#
1
2
3
4
5
6
7
8
9
10
11
  static void Main(string[] args)
        {
            Socket forConn = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            forConn.BeginConnect(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 9095), new AsyncCallback(EndConnection), forConn);
           
                string s = Console.ReadLine();
                forConn.BeginSend(Encoding.UTF8.GetBytes(s), 0, Encoding.UTF8.GetByteCount(s), 0, new AsyncCallback(EndSending), forConn);
 
 
                Console.Read();
        }
Вечного цикла нет,а поток Main-a главный, - значит он сразу завершает работу после Console.ReadLine ,а если в приложении один главный поток, и неважно какое число фоновых, то все они тоже завершают работу. Так что повторный вызов BeginConnect из callback метода не будет работать.

Добавлено через 6 минут
Вот это должно помочь. Всего лишь то, что нужно было сделать.
C#
1
2
3
4
5
while(true)
{
 string s = Console.ReadLine();
                forConn.BeginSend(Encoding.UTF8.GetBytes(s), 0, Encoding.UTF8.GetByteCount(s), 0, new AsyncCallback(EndSending), forConn);
}
так я же в шапке написал
Я, конечно, понимаю, что можно сделать вечный цикл и в нем запрашивать ввод данных и после этого отправлять их, но если нужно будет еще и принимать данные?? я же не смогу сделать два вечных цикла.
0
 Аватар для IamRain
4694 / 2702 / 734
Регистрация: 02.08.2011
Сообщений: 7,228
08.03.2013, 16:23
а можно и одним обойтись - воткнуть BeginReceive в этот цикл до вызова BeginSend и если число полученных байт больше нуля, то отображать сообщение. Как-то так.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
08.03.2013, 16:23
Помогаю со студенческими работами здесь

Асинхронный SMTP клиент
Приветствую! Возникла задача в написании собственного SMTP клиента, для отправки электронной почты! Задача решена, но с использованием...

Отправка данных из формы о том, что и сколько выбрал клиент, на почту
Имеется во такой калькулятор: <div class="vertical-footer-right"> <div class="spinner-box-9 spinner-box-9-right...

Асинхронный клиент-сервер. Рассылка от сервера
Здравствуйте! Пишу клиент - серверное приложения на асинхронных сокетах. Задача состоит в том, чтобы при получении сервером...

Асинхронный сервер и клиент Boost Asio
Здравствуйте. Попробовал написать нечто такое. Но на этом этапе чтения не происходит ничего. Дальше std::cout<<"Server: I...

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


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

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Новые блоги и статьи
Подключение Box2D v3 к SDL3 для Android: физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL3_image
8Observer8 27.01.2026
Содержание блога SDL3_image - это библиотека для загрузки и работы с изображениями. Эта пошаговая инструкция покажет, как загрузить и вывести на экран смартфона картинку с альфа-каналом, то есть с. . .
Влияние грибов на сукцессию
anaschu 26.01.2026
Бифуркационные изменения массы гриба происходят тогда, когда мы уменьшаем массу компоста в 10 раз, а скорость прироста биомассы уменьшаем в три раза. Скорость прироста биомассы может уменьшаться за. . .
Воспроизведение звукового файла с помощью SDL3_mixer при касании экрана Android
8Observer8 26.01.2026
Содержание блога SDL3_mixer - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
Установка Android SDK, NDK, JDK, CMake и т.д.
8Observer8 25.01.2026
Содержание блога Перейдите по ссылке: https:/ / developer. android. com/ studio и в самом низу страницы кликните по архиву "commandlinetools-win-xxxxxx_latest. zip" Извлеките архив и вы увидите. . .
Вывод текста со шрифтом TTF на Android с помощью библиотеки SDL3_ttf
8Observer8 25.01.2026
Содержание блога Если у вас не установлены Android SDK, NDK, JDK, и т. д. то сделайте это по следующей инструкции: Установка Android SDK, NDK, JDK, CMake и т. д. Сборка примера Скачайте. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru