Страница 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
Мурик
Кислый писал(а):Асинхронные = неблокирующие
Это не одно и тоже. Читайте. http://www.programmersforum.ru/showthread.php?t=231061
http://samolisov.blogspot.com/2013/11/java.html
http://hashcode.ru/questions/371655/c-в ... инхронными
http://uinc.ru/articles/23/

Re: Архитектура приложения с асинхронными сокетами

Добавлено: Чт янв 01, 2015 20:54:14
urry
Я все равно не понимаю суть проблемы. В случае серверного варианта определяется максимальное количество сокетов, производных от листающего, который тот обязан обработать. Каждый новый сокет обмена открывается в своем потоке - это правило хорошего тона, да так, собственно, и проще. Евент акцепт - на открытие потока, евент рид - чтение, евент слозе - закрытие.
Никто ничего нового не придумал. С чего у вас создается сокет при чтении ??? Что он может читать, он не настроен ... При акцепте переписываются из листающего сокета в новый сокет данные - айпишник клиентского, порт...

Re: Архитектура приложения с асинхронными сокетами

Добавлено: Чт янв 01, 2015 21:04:56
Кислый
urry, должно быть потому, что у меня клиент.

Re: Архитектура приложения с асинхронными сокетами

Добавлено: Чт янв 01, 2015 21:10:13
Мурик
urry писал(а):Каждый новый сокет обмена открывается в своем потоке - это правило хорошего тона
Что за ересь? :shock: :shock: :o :o
Знаете что число потоков ограничено? Если делать по нормальному, достаточно одного параллельного потока для множества коннектов, как в случае клиента, так в случае сервера.
За примером далеко ходить не надо. У вас есть торрент-клиент? Он кроме установки коннектов (т. е. выполнения роли клиента) создает так же сервер для входящих соединений. Посмотрите сколько создается потоков. Это расходится с вашим предложением! Правило хорошего тона, наоборот, использовать как можно меньше потоков если задачу можно решить без них.

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 писал(а):Каждый новый сокет обмена открывается в своем потоке - это правило хорошего тона
Если вы считаете что правило хорошего тона, это работа каждым соединением в отдельном параллельном потоке, плиз встудию линки на авторитетные источники где это доказано.