Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Обмен сообщениями клиент-сервер, по tcp 
:(
    Опции темы
V0fka
Дата 15.2.2014, 17:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 311
Регистрация: 5.11.2006
Где: Украина

Репутация: нет
Всего: нет



Привет!

Что нужно сделать. На сервере крутится программа, которая принимает входящие подключения от клиентов и при возникновении определенного события - отсылает им сообщения. Клиенты принимают сообщения и как-то реагируют. Клиентов планируется на данном этапе порядка 100.

1) Сервер:

Сервер был сделан с помощью класса TcpListener. Далее в бесконечном цикле вызывается его метод AcceptTcpClient() и после полученный TcpClient добавляется в коллекцию clients. Это происходит не в основном потоке.

Для отправки сообщений в цикле обходится коллекция clients и для каждого элемента выполняется io = client.GetStream()  и потом io.Write(...);

2) Клиент:

Используется класс Socket. В бесконечном цикле выполняется метод Receive и тут же эти данные обрабатываются и выполняются какие-то действия. Это происходит не в основном потоке.

/////////////////

Я не особо шарю с C#, поэтому хотелось бы получить совет от людей, которые шарят, правильно ли выбрано направление для решения этой задачи:
1) Те ли классы я использую для сервера и клиента?
2) Если одновременно к серверу будет подключаться несколько клиентов, то используя в бесконечном цикле AcceptTcpClient() - я не пропущу никого из них?
3) Правильно ли на клиенте я "слушаю" сообщения? Меня смущает бесконечный цик там. Возможно это так делают, просто хочу узнать. Если же нет, то подскажите, пожалуйста, как надо.

На данном этапе в детали не вдаюсь, т.к. вопросов тысяча. Просто хочу узнать правильное направление, чтобы когда уже будет виден финиш не обломиться из-за того, что в начале что-то не так было сделано.

Спасибо!

Это сообщение отредактировал(а) V0fka - 15.2.2014, 17:39
PM MAIL   Вверх
jonie
Дата 17.2.2014, 09:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 6
Всего: 118



Цитата(V0fka @  15.2.2014,  18:37 Найти цитируемый пост)

1) Те ли классы я использую для сервера и клиента?

можно и эти. Кстати есть класс TcpClient раз уж пошла речь..

Цитата(V0fka @  15.2.2014,  18:37 Найти цитируемый пост)

2) Если одновременно к серверу будет подключаться несколько клиентов, то используя в бесконечном цикле AcceptTcpClient() - я не пропущу никого из них?

если не будете долго тупить в "добавлении клиентов в очередь" то не должны бы...

Цитата(V0fka @  15.2.2014,  18:37 Найти цитируемый пост)

3) Правильно ли на клиенте я "слушаю" сообщения? Меня смущает бесконечный цик там. Возможно это так делают, просто хочу узнать. Если же нет, то подскажите, пожалуйста, как надо.
вообще можно использовать асинхронное API, но если не критично то можно крутить и цикл.



--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
V0fka
Дата 19.2.2014, 12:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 311
Регистрация: 5.11.2006
Где: Украина

Репутация: нет
Всего: нет



Цитата(jonie @  17.2.2014,  09:17 Найти цитируемый пост)
можно и эти. Кстати есть класс TcpClient раз уж пошла речь..

А какое преимущество TcpClient-а, в данном случае, будет?

Цитата(jonie @  17.2.2014,  09:17 Найти цитируемый пост)
если не будете долго тупить в "добавлении клиентов в очередь" то не должны бы...

Ясно, спасибо!

Цитата(jonie @  17.2.2014,  09:17 Найти цитируемый пост)
вообще можно использовать асинхронное API, но если не критично то можно крутить и цикл.

Правильно я вас понял, асинхронно - это, например, так: http://cyber-blog.klan-hub.ru/2010/08/28/а...етами-в-c-шарп/  ? Если да, то у меня здесь появилась проблемка. В классе Server я подключенных клиентов собираю в коллекцию:

Код

private void AcceptCompleted(object sender, SocketAsyncEventArgs e)
 {
     if (e.SocketError == SocketError.Success)
     {
         Dispatcher.Invoke(...);
     }
     e.AcceptSocket = null;
     AcceptAsync(AcceptAsyncArgs);
 }


и у меня возникает ошибка, как здесь: http://forum.vingrad.ru/forum/topic-336459.html: Для нестатического поля, метода или свойства "System.Windows.Threading.Dispatcher.Invoke(System.Delegate, params object[])" требуется ссылка на объект.

Я её решил, передавая экземпляр Dispatcher в объект класса Server и соответственно вызываю Invoke через этот переданный диспатчер. Но, как всегда, есть сомнения насчет применения такого подхода. Хотелось бы получить "благословение" либо пинок в нужную сторону от знающих smile .

Это сообщение отредактировал(а) V0fka - 19.2.2014, 12:27
PM MAIL   Вверх
jonie
Дата 19.2.2014, 14:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 6
Всего: 118



а зачем связывать очередь с UI ?!


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
V0fka
Дата 19.2.2014, 16:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 311
Регистрация: 5.11.2006
Где: Украина

Репутация: нет
Всего: нет



Сервер - это WPF приложение. На форме есть ListView, к которому биндится очередь и видно кто подключен сейчас.

Это сообщение отредактировал(а) V0fka - 19.2.2014, 16:38
PM MAIL   Вверх
jonie
Дата 19.2.2014, 17:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 6
Всего: 118



Цитата(V0fka @  19.2.2014,  17:38 Найти цитируемый пост)
 На форме есть ListView, к которому биндится очередь и видно кто подключен сейчас.

и чО?
Очередь просто должна уметь уведомлять подписчиком что что-то поменялось, а те уже в своих обработчиках должны решать как на эти действия реагировать - плохая идея добавлять данные в UI потоке.


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
V0fka
Дата 21.2.2014, 10:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 311
Регистрация: 5.11.2006
Где: Украина

Репутация: нет
Всего: нет



Цитата(jonie @  19.2.2014,  17:52 Найти цитируемый пост)
и чО?

Я по вашему совету переделал сервер и клиент с использованием асинхронных методов. Конкретно сервер работает через AcceptAsync(...). И в результате когда хочу в коллекцию (а это ObservableCollection) добавить элемент, то Visual Studio говорит, что "нельзя добавить из этого потока" (ошибка не дословная, но я думаю, вы поняли что это). Тогда я нагуглил, что нужно добавлять через Dispatcher.Invoke. Попрбовал, но получил ошибку, которую выше озвчучил. После этого сделал так, как написал.

Цитата(jonie @  19.2.2014,  17:52 Найти цитируемый пост)
Очередь просто должна уметь уведомлять подписчиком что что-то поменялось, а те уже в своих обработчиках должны решать как на эти действия реагировать - плохая идея добавлять данные в UI потоке.

Можете пример какой-то привести, как это на примере WPF делается?
PM MAIL   Вверх
V0fka
Дата 21.2.2014, 11:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 311
Регистрация: 5.11.2006
Где: Украина

Репутация: нет
Всего: нет



По ходу разбирательств возник новый вопрос. Есть на сервере коллекция подключенных клиентов. В цикле обхожу её и методом Send хочу отправить сообщение. Все классно работает, если клиент подключен. Но если он отключен, то сервер виснет. Начал искать решения:
1) Установил на сервере в Socket.SendTimeout = 1, сделал через try catch отправку и если код попадает в catch - то клиент из коллекции удаляется. Подскажите, можно ли так делать, если планируется около 100 подключенных клиентов?
2) Обхожу коллекцию. Проверяю статус клиента IsConnected. Если IsConnected = false, то удаляю элемент из коллекции, если true, то отправляю сообщение. Но тут я заметил, что между проверкой и отправкой сообщения этот статус может поменяться и получается, что в момент Send клиента уже нету.
Вопрос: как правильно проверять активных клиентов, чтобы им дошли сообщения?

Это сообщение отредактировал(а) V0fka - 21.2.2014, 11:23
PM MAIL   Вверх
jonie
Дата 21.2.2014, 12:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 6
Всего: 118



Цитата(V0fka @  21.2.2014,  11:07 Найти цитируемый пост)

Можете пример какой-то привести, как это на примере WPF делается? 

для .net 4.5 имеется BindingOperations.EnableCollectionSynchronization, а для других версий можно написать свою коллекцию же, с маршалингом вызовов callback делегатов в нужном SyncronizationContext-е.


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
V0fka
Дата 21.2.2014, 15:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 311
Регистрация: 5.11.2006
Где: Украина

Репутация: нет
Всего: нет



jonie, очередной раз я вам признателен за ответ, но что делать с BindingOperations.EnableCollectionSynchronization я в упор не пойму. Был бы очень признателен за примеры кода (псевдокода).
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
Partizan
PashaPash

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, Partizan, PashaPash.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | .NET для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0517 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.