Страница 1 из 1
Архитектура приложения с асинхронными сокетами
Добавлено: Ср дек 31, 2014 12:43:57
Кислый
Я не могу разобраться с асинхронными сокетами, прошу посильной помощи от вас.
Задача следующая :
1. Есть некий сервер, который после подключения клиента может в любой момент прислать данные, и клииент должен успеть их принять.
2. Если пришедший пакет требует ответа, то ответить не медля.
3. В случае некоторого евента ( например нажатия кнопки в окне клиента) отправляем пакет серверу.
Я позолил себе набросать небольшую схему, как я это вижу.
Архитектура приложения с асинхронными сокетами
Receive - в цикле, Send - c кнопки и\или ответом. Чего не хватает ?
Чего я не понимаю:
1) как определить что в сокет пришли данные ?
2) можно ли не гонять цикл, а ждать некоторого interrupt , который оповестит о готовности некоторого обьема данных ?
3) ???
Очень надеюсь на вашу помощь. С наступающим новым годом и рождеством !!

Re: Архитектура приложения с асинхронными сокетами
Добавлено: Ср дек 31, 2014 22:32:46
urry
.Если винда, то генерируются winsock2.dll (надеюсь, правильно вспомнил, как пишется) 2 события - 1 пришли данные 2 сокет закрыл обмен. Да, это колбэк.
Я на вертепе статью писАл с примером
http://vrtp.ru/index.php?act=categories ... ticle=3549
Политику убрал.
Если уж совсем не в "терпеж" то с этим в раздел МЯУ.
aen
Re: Архитектура приложения с асинхронными сокетами
Добавлено: Чт янв 01, 2015 14:28:11
Кислый
Во-первых, не надо ругаться матом вне "Мяу". Во-вторых, матом ругаться вообще вредно : зубные протезы нынче стоят
дорого. В третьих, не стоит говорить о людях плохо, тем более за глаза Это смахивает на мелкое пакостничество. В четвертых, я думаю не стоит кидать предьяву мне по поводу постороннего человека! (Собственно поэтому я не люблю фудбольных (и прочих) фанатов)
Да, возвращаясь к теме, я к сожалению забыл написать, что использую Mono : собственно никаких winsock там нет.
Re: Архитектура приложения с асинхронными сокетами
Добавлено: Чт янв 01, 2015 17:20:43
Мурик
Кислый писал(а):может в любой момент прислать данные, и клииент должен успеть их принять.
Почему не успеет? Данные буферизируются и если что, сетевой протокол предусматривает повторный запрос пакета. Если возникли проблемы с потерей пакетов, то наверное в коде баг.
Кислый писал(а):Если пришедший пакет требует ответа, то ответить не медля.
Какова допустимая задержка? При этом учитываете что при некоторых условиях, даже если ваша программа ответит сразу же (в идеальном случае, в нулевой задержкой) ответ сервер может получить больше чем через секунду.
По моему, для этой задачи достаточно неблокирующих сокетов.
Re: Архитектура приложения с асинхронными сокетами
Добавлено: Чт янв 01, 2015 17:24:05
Кислый
Я и хочу использовать неблокирующие сокеты. Поробовал написать короткий код, возникла уйма дополнительных вопросов
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace l2packet
{
class SocketAsyncClient
{
public Socket client;
public byte[] in_data = new byte[0xFFFF];
public byte[] out_data = new byte[0xFFFF];
public SocketAsyncClient()
{
this.connect (ref client);
while (true) {
this.s_read ();
}
client.Shutdown (SocketShutdown.Both);
client.Close ();
}
public void connect(ref Socket sock)
{
sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
try
{
Console.WriteLine("Сокет успешно создан");
client.Connect("127.0.0.1", 2106);
Console.WriteLine("Соединение успешно установлено");
}
catch (SocketException ex)
{
Console.WriteLine("Ошибка при работе с сокетами: " + ex.Message);
}
}
public int s_read()
{
byte[] data = new byte[1024];
// … заполнение массива data опущено
SocketAsyncEventArgs async_e = new SocketAsyncEventArgs();
async_e.SetBuffer(data, 0, 1024);
async_e.Completed += SocketAsyncCompleted;
client.ReceiveAsync(async_e);
Console.WriteLine("Нажмите любую клавишу");
Console.ReadKey();
Console.WriteLine ("Приняты байты : {0} {1}", data [0], data [1]);
return 0;
}
public int s_send()
{
byte[] data = new byte[1024];
// … заполнение массива data опущено
SocketAsyncEventArgs async_e = new SocketAsyncEventArgs();
async_e.SetBuffer(data, 0, 1024);
async_e.Completed += SocketAsyncCompleted;
client.SendAsync(async_e);
return 0;
}
void SocketAsyncCompleted(object o, SocketAsyncEventArgs e)
{
if(e.LastOperation == SocketAsyncOperation.Send)
{
if(e.SocketError == SocketError.Success)
Console.WriteLine("Передача выполнена успешна");
else
Console.WriteLine("При передаче произошла ошибка");
}
if(e.LastOperation == SocketAsyncOperation.Receive)
{
if(e.SocketError == SocketError.Success)
Console.WriteLine("Прием выполнен успешно");
else
Console.WriteLine("При приеме произошла ошибка");
}
}
}
}
обьясните, почему если нет задержки, обусловленной Console.ReadKey();, то код возвращает пустой массив. как этого избежать ? прошу не путать вопрос с областью видимости. я сознательно обьявляю массив внутри функции, для частоты эксперемента.. так сказать.
Re: Архитектура приложения с асинхронными сокетами
Добавлено: Чт янв 01, 2015 17:34:33
urry
для начала - мои соболезнования.
далее - насчет "сокетов там нет" - юзаются те же длл - судя по почерку
https://github.com/mono/mono/blob/maste ... /Socket.cs
колбэковские функции и не нужно изобретать велосипед.
Re: Архитектура приложения с асинхронными сокетами
Добавлено: Чт янв 01, 2015 17:40:31
Кислый
urry, не надо хамить и хулиганить. Хочется трололо - идите в мяу.
С коллбаками получится какая-то херня поток на потоке и потоком погоняет.
Re: Архитектура приложения с асинхронными сокетами
Добавлено: Чт янв 01, 2015 18:09:00
Мурик
Кислый писал(а):Я и хочу использовать неблокирующие сокеты.
Но в коде асинхронные.
Код: Выделить всё
SocketAsyncEventArgs async_e = new SocketAsyncEventArgs();
Кислый писал(а):обьясните, почему если нет задержки, обусловленной Console.ReadKey();, то код возвращает пустой массив.
Потому что сокет асинхронный. Данные в массив пишутся не в момент вызова функции (метода), а когда они будут приняты. Без задержки массив пустой потому что сервер еще ничего не успел прислать. Лучше используйте неблокирующие сокеты. Или прочитайте про асинхронные сокеты чтобы понимать как они устроены и работают.
Re: Архитектура приложения с асинхронными сокетами
Добавлено: Чт янв 01, 2015 19:26:43
Кислый
Хмм.. ничего не путаете ? Асинхронные = неблокирующие
подправил до :
Код: Выделить всё
public int s_read()
{
byte[] data = new byte[1024];
// … заполнение массива data опущено
SocketAsyncEventArgs async_e = new SocketAsyncEventArgs();
async_e.SetBuffer(data, 0, 1024);
async_e.Completed += SocketAsyncCompleted;
while (true) {
if (client.Available > 0) {
client.ReceiveAsync (async_e);
Console.WriteLine ("Приняты байты : {0} {1}", data [0], data [1]);
break;
}
}
return 0;
}
не слишком убого ?
Re: Архитектура приложения с асинхронными сокетами
Добавлено: Чт янв 01, 2015 20:08:29
Мурик
Re: Архитектура приложения с асинхронными сокетами
Добавлено: Чт янв 01, 2015 20:54:14
urry
Я все равно не понимаю суть проблемы. В случае серверного варианта определяется максимальное количество сокетов, производных от листающего, который тот обязан обработать. Каждый новый сокет обмена открывается в своем потоке - это правило хорошего тона, да так, собственно, и проще. Евент акцепт - на открытие потока, евент рид - чтение, евент слозе - закрытие.
Никто ничего нового не придумал. С чего у вас создается сокет при чтении ??? Что он может читать, он не настроен ... При акцепте переписываются из листающего сокета в новый сокет данные - айпишник клиентского, порт...
Re: Архитектура приложения с асинхронными сокетами
Добавлено: Чт янв 01, 2015 21:04:56
Кислый
urry, должно быть потому, что у меня клиент.
Re: Архитектура приложения с асинхронными сокетами
Добавлено: Чт янв 01, 2015 21:10:13
Мурик
urry писал(а):Каждый новый сокет обмена открывается в своем потоке - это правило хорошего тона
Что за ересь?
Знаете что число потоков ограничено? Если делать по нормальному, достаточно одного параллельного потока для множества коннектов, как в случае клиента, так в случае сервера.
За примером далеко ходить не надо. У вас есть торрент-клиент? Он кроме установки коннектов (т. е. выполнения роли клиента) создает так же сервер для входящих соединений. Посмотрите сколько создается потоков. Это расходится с вашим предложением! Правило хорошего тона, наоборот, использовать как можно меньше потоков если задачу можно решить без них.
Re: Архитектура приложения с асинхронными сокетами
Добавлено: Чт янв 01, 2015 21:23:34
urry
urry, должно быть потому, что у меня клиент.
И что ? После посылки коннекта серверу, если коннект прошел, кстати, только после этого разрешается взводить евент на прием данных. сколько серверов - столько и клиентских потоков. Один - достаточно одного.
Что за ересь?

Посмотрите количество потоков вашего браузера - любого...
Re: Архитектура приложения с асинхронными сокетами
Добавлено: Чт янв 01, 2015 21:36:51
Мурик
urry писал(а):Посмотрите количество потоков вашего браузера - любого
Число потоков около десятка и не меняется при открытии/закрытии вкладок/страниц. Видимо число потоков не имеет прямого отношения к работе с сетью.
Re: Архитектура приложения с асинхронными сокетами
Добавлено: Чт янв 01, 2015 21:58:50
urry
http://msdn.microsoft.com/ru-ru/library/dd335942.aspx

У нас разные браузеры. По опыту работы - многопотоковый вывод быстрее. Я не имею в виду 4000 потоков, естественно, обычные рабочие задачи. 2 года назад пришлось очень плотно работать по этой теме, так что можете поверить на слово.
С другой стороны - никто не мешает наступить на грабли самостоятельно.

Re: Архитектура приложения с асинхронными сокетами
Добавлено: Чт янв 01, 2015 22:29:45
Мурик
urry писал(а):многопотоковый вывод быстрее.
urry писал(а):никто не мешает наступить на грабли самостоятельно.

Про грабли могу аналогичное сказать когда будете синхронизировать 1500 потоков. И из-за этого скорость получится куда меньше чем для однопоточного режима.
Для работы сервера/клиента достаточно одного потока и неважно сколько будет соединений.
Re: Архитектура приложения с асинхронными сокетами
Добавлено: Чт янв 01, 2015 22:46:53
urry
я не буду синхронизировать 1500 потоков - нет такой задачи. До полсотни клиентов довольно резво вязались вместе - каждый на своем потоке. Эта задача мной была реализована, в одном потоке я бы ее не решал, образование не позволяет.
Впрочем, пошел флуд... Свой вариант в 1 потоке я показал в начале ветки, ваш ?
"Слова ничего не значат, покажите код" (с) Линус Торвальдс
Re: Архитектура приложения с асинхронными сокетами
Добавлено: Пт янв 02, 2015 01:18:59
Мурик
urry писал(а):Свой вариант в 1 потоке я показал в начале ветки, ваш ?
Что за детский сад?
Как это поможет ТС?
Я писал выше что по возможности работать с сетью лучше из одного потока. И это был ответ на ваше ИМХО сбивающее столку высказывание.
urry писал(а):Каждый новый сокет обмена открывается в своем потоке - это правило хорошего тона
Если вы считаете что правило хорошего тона, это работа каждым соединением в отдельном параллельном потоке, плиз встудию линки на авторитетные источники где это доказано.