Аналог ICQ (Клиент-Сервер), как написать?
От: Andy Panda США  
Дата: 31.05.04 08:55
Оценка:
Где можно почитать про принципы построения подобных программ?

Надо сделать что-то вроде ICQ, для локальной сети.
Пользователи подключаются к серверу, обмениваются сообщениями через него. Общение пользователь-пользователю (или группе пользователей).
Общего чата нет.
Клиент-сервер выбран потому, что нужно ведение логов общения всей сети, возможности блокирования определенных пользователей (к примеру перевод в read-only) — мне кажется, что это проще всего делать через сервер.
Поскольку опыта работы с подобными приложениями никакого не имею, а писать надо (диплом), то хочется почитать теорию и практику.
Писать хочу на C#
Пока что вопросы, которые возникли.

Какой протокол чаще используется для подобных задач — TCP или UDP?
Необходима ли для данной задачи многопоточность сервера?
Если да, то как реализовать анализ того, от какого клиента пришло сообщение, и передачу этого сообщения нужному потоку-обработчику?
Как придумать протокол общения клиента и сервера?
Re: Аналог ICQ (Клиент-Сервер), как написать?
От: Tom Россия http://www.RSDN.ru
Дата: 31.05.04 09:01
Оценка:
AP>Как придумать протокол общения клиента и сервера?
Лучше сразу думать о HTTP.

А вообще смотри в сторону Remoting.
Народная мудрось
всем все никому ничего(с).
Re: Аналог ICQ (Клиент-Сервер), как написать?
От: Nuald Россия http://nuald.blogspot.com
Дата: 31.05.04 09:14
Оценка:
Здравствуйте, Andy Panda, Вы писали:

Мы в свое время писали ICQ-сервер (http://iserverd.khstu.ru/), так что есть некоторый опыт

AP>Какой протокол чаще используется для подобных задач — TCP или UDP?


Для синхронной работы — TCP, для асинхронной — UDP. Обычно требуется первое (скажем, если вы хотите иметь подтверждение на доставку сообщения без лишних внутренних сообщений).

AP>Необходима ли для данной задачи многопоточность сервера?


Конечно

AP>Если да, то как реализовать анализ того, от какого клиента пришло сообщение, и передачу этого сообщения нужному потоку-обработчику?


От клиента приходит UDP-сообщение в котором зашита вся инфа. После получения сервер создает новый поток, в котором идет обработка этого сообщения.

AP>Как придумать протокол общения клиента и сервера?


Сервер нужен лишь для хранения контакт-листов и IP-адресов. После инициализации коннекта к серверу, общение с другими пользователями идет напрямую через TCP-протокол, что очень сильно снижает нагрузку на сервер.
Из этого мы имеем два протокола общения. А придумывать особо ничего не надо. Можно просто создать классы сообщений, сериализовать их в XML, упаковать ZIP-ом (вроде даже есть какие-то классы для этого), и отсылать. А по пришествии ответа делать обратную процедуру, благо в .NET все это просто. Хотя боюсь, что используя .NET будет невысокая производительность — мы у себя все писали на C++.
Re: Аналог ICQ (Клиент-Сервер), как написать?
От: mayevski  
Дата: 31.05.04 09:23
Оценка:
Здравствуйте, Andy Panda, Вы писали:

AP>Какой протокол чаще используется для подобных задач — TCP или UDP?

AP>Необходима ли для данной задачи многопоточность сервера?
AP>Если да, то как реализовать анализ того, от какого клиента пришло сообщение, и передачу этого сообщения нужному потоку-обработчику?
AP>Как придумать протокол общения клиента и сервера?

В качестве транспорта можете посмотреть на MsgConnect (http://www.msgconnect.com). Там есть GPL-редакция (правда, она не для .NET), можно посмотреть.

С уважением,
Евгений Маевский
Re: Аналог ICQ (Клиент-Сервер), как написать?
От: NoFate Россия  
Дата: 31.05.04 09:50
Оценка:
Здравствуйте, Andy Panda, Вы писали:

AP>Где можно почитать про принципы построения подобных программ?

Программирование в сетях Microsoft Windows, имхо, очень хорошая книга.

AP>Писать хочу на C#

Почему?

AP>Какой протокол чаще используется для подобных задач — TCP или UDP?

TCP — протокол, создающий соединение. UDP — нет. Это влияет на скорость и надёжность...

AP>Необходима ли для данной задачи многопоточность сервера?

Это зависит от реализации. Я делал бы на TCP и использовал бы асинхронную модель ввода-вывода. Тогда конечно многопоточность...

AP>Если да, то как реализовать анализ того, от какого клиента пришло сообщение, и передачу этого сообщения нужному потоку-обработчику?

Ну... Если делать, как я предлагал, то передаётся сообщение. В wParam, кажется, находится сокет, сгенерировавший сообщение.

AP>Как придумать протокол общения клиента и сервера?

Что значит как? Это зависит от требований безопасности, имхо.
... << RSDN@Home 1.1.3 stable silent>>
Re[2]: Аналог ICQ (Клиент-Сервер), как написать?
От: Maxim S. Shatskih Россия  
Дата: 01.06.04 06:37
Оценка:
AP>>Необходима ли для данной задачи многопоточность сервера?
N>Конечно

Если под юниксом — то не обязательно.

N>От клиента приходит UDP-сообщение в котором зашита вся инфа. После получения сервер

>создает новый поток, в котором идет обработка этого сообщения.

Неоптимально. Надо иметь пул потоков, и пробуждать один из них при приходе сообщения. Проще всего — все потоки из пула сидят в recvfrom на сокете, тогда каждому по сообщению достанется.

На деле в .NET это все уже готовое есть.

AP>>Как придумать протокол общения клиента и сервера?


>процедуру, благо в .NET все это просто. Хотя боюсь, что используя .NET будет невысокая

>производительность — мы у себя все писали на C++.

Первое. Разница в производительности CLR и машинного кода малозаметна, тем более что тут задача процессор не нагружает.
Второе. Производительность вот конкретно этой задачи зависит от продуманности того, как сервер с сокетами работает, а не от CLR или машинного кода.
Занимайтесь LoveCraftом, а не WarCraftом!
Re[2]: Аналог ICQ (Клиент-Сервер), как написать?
От: Maxim S. Shatskih Россия  
Дата: 01.06.04 06:43
Оценка:
AP>>Писать хочу на C#
NF>Почему?

Потому что куча готовых компонент. Собственно, там вся архитектура сервера уже готовая — и работа с сокетами, и пулы нитей.

AP>>Какой протокол чаще используется для подобных задач — TCP или UDP?

NF>TCP — протокол, создающий соединение. UDP — нет. Это влияет на скорость и
>надёжность...

Влияет в худшую сторону для общения по TCP надо сначала коннект установить, а это займет RTT туда-обратно.

TCP плохо подходит для транзакционного траффика "вопрос-ответ", это давно известно. Если и вопрос, и ответ гарантированно меньше 64К — то лучше UDP, но при этом самостоятельно придется писать ретрансмиты.

Если использовать TCP — то обязательно выставить TCP_NODELAY.

NF>Ну... Если делать, как я предлагал, то передаётся сообщение. В wParam, кажется,

>находится сокет, сгенерировавший сообщение.

Смешивать GUIшные сообщения и сокеты — верх уродства. Времена Win16 давно прошли.

AP>>Как придумать протокол общения клиента и сервера?

NF>Что значит как? Это зависит от требований безопасности, имхо.

Взять готовый из .NET как вариант.
Занимайтесь LoveCraftом, а не WarCraftом!
Re[3]: Аналог ICQ (Клиент-Сервер), как написать?
От: NoFate Россия  
Дата: 01.06.04 10:50
Оценка:
Здравствуйте, Maxim S. Shatskih, Вы писали:

MSS>Смешивать GUIшные сообщения и сокеты — верх уродства.

Ну-ну... Я бы не был таким убеждённым. Кстати, при чём тут GUI сообщения? Windows использует сообщения не только от графического пользовательского интерфейса...
... << RSDN@Home 1.1.3 stable silent>>
Re[4]: Аналог ICQ (Клиент-Сервер), как написать?
От: Maxim S. Shatskih Россия  
Дата: 01.06.04 13:06
Оценка:
MSS>>Смешивать GUIшные сообщения и сокеты — верх уродства.
NF>Ну-ну... Я бы не был таким убеждённым.

Ну а к чему ляпать все подряд в одну кучу? нужно сообщение о завершении IO — есть IO completion port.

WM_xxx сообщение об операции на сокете — это рудимент и атавизм времен Win16, где многозадачности не было.
Занимайтесь LoveCraftом, а не WarCraftом!
Re[5]: Аналог ICQ (Клиент-Сервер), как написать?
От: Аноним  
Дата: 01.06.04 13:22
Оценка: -1
MSS>WM_xxx сообщение об операции на сокете — это рудимент и атавизм времен Win16, где многозадачности не было.
Не позорился бы, умник...тьфу
Re[2]: Аналог ICQ (Клиент-Сервер), как написать?
От: Andy Panda США  
Дата: 01.06.04 13:55
Оценка:
Здравствуйте, Tom, Вы писали:

AP>>Как придумать протокол общения клиента и сервера?

Tom>Лучше сразу думать о HTTP.

Tom>А вообще смотри в сторону Remoting.


Да, возможно так и буду делать.
Re[5]: Аналог ICQ (Клиент-Сервер), как написать?
От: NoFate Россия  
Дата: 01.06.04 15:00
Оценка:
Здравствуйте, Maxim S. Shatskih, Вы писали:

MSS>Ну а к чему ляпать все подряд в одну кучу? нужно сообщение о завершении IO — есть IO completion port.

Э-э-э Ну что я могу сказать... Сейчас все сетевики, уверен, кинутся делать приложения на IO completion port. Смысл работать с IOCP есть только если приложение должно работать с сотнями и тысячами сокетов. И эффективна эта модель ввода-вывода только на мощных серверах. А для сетевого пейджера (или чата), думаю, не нужна 16-процессорная тачка... Короче, использовать нужно асинхронную модель ввода-вывода. При этом для Windows быстрее и удобнее работать с сообщениями.

MSS>WM_xxx сообщение об операции на сокете — это рудимент и атавизм времен Win16, где многозадачности не было.

Ага! Сейчас рулит искусственный интеллект, квантовые компьютеры, а всё остальное атавизм
... << RSDN@Home 1.1.3 stable silent>>
Re[6]: Аналог ICQ (Клиент-Сервер), как написать?
От: Maxim S. Shatskih Россия  
Дата: 01.06.04 16:09
Оценка:
NF>Э-э-э Ну что я могу сказать... Сейчас все сетевики, уверен, кинутся
>делать приложения на IO completion port. Смысл работать с IOCP есть только если
>приложение должно работать с сотнями и тысячами сокетов.

Основания утверждать такое?

>И эффективна эта модель ввода-вывода только на мощных серверах.


А основания утвеждать вот это?

MSS>>WM_xxx сообщение об операции на сокете — это рудимент и атавизм времен Win16, где

>многозадачности не было.
NF>Ага! Сейчас рулит искусственный интеллект, квантовые компьютеры, а всё остальное
>атавизм

Я бы предпочел не иметь ни одного обращения в user32 из серверной софтины. Ну как-то противно оно мне и все. Зачем уровни мешать? GUI — оно GUI, и при чем тут сервера?

А теперь отодвинем вкусы в сторону и посмотрим на реальность

IOCP — почти такая же по сути очередь сообщений, что и GetMessage/PostMessage. Разница по большей части в том, что в случае IOCP "разбирать" сообщения с принимающего конца трубы могут сразу много нитей, а в случае GetMessage — увы, одна! Гуевая очередь сообщений принципиально привязана к одной-единственной нити. Окно, кстати, тоже.

Получается принципиально однонитевое приложение, которое еще и GetMessage должно звать раз в какое-то время. Толку от асинхронности-то? Что несколько сокетов можно сразу обслужить? Ну так для такой картины — одна нитка, много сокетов — есть старый добрый select(), заодно с юниксом совместимый еще один вариант — пользоваться ReadFileEx и потом alertable waits, тоже дело.
Занимайтесь LoveCraftом, а не WarCraftом!
Re[3]: Аналог ICQ (Клиент-Сервер), как написать?
От: Nuald Россия http://nuald.blogspot.com
Дата: 02.06.04 01:49
Оценка: 1 (1)
Здравствуйте, Andy Panda, Вы писали:

Tom>>А вообще смотри в сторону Remoting.


AP>Да, возможно так и буду делать.


IMHO, Remoting — плохая идея — был бы я дипломным руководителем, я бы с таким студентом разговор бы имел короткий. Это то же самое, что стрелять из пушки по воробьям. Впрочем, в наше время в связи с агрессивным маркетингом новых архитектур (J2EE, .NET) удивляться нечему...
Никто уже не поверит, что написать простейший аналог IRC требует всего несколько сотен строчек кода, несколько дестятков килобайт памяти сервера и отсутствия всяческих framework-ов и виртуальных машин.
Re[7]: Аналог ICQ (Клиент-Сервер), как написать?
От: NoFate Россия  
Дата: 02.06.04 04:30
Оценка:
Здравствуйте, Maxim S. Shatskih, Вы писали:

NF>>Э-э-э Ну что я могу сказать... Сейчас все сетевики, уверен, кинутся

>>делать приложения на IO completion port. Смысл работать с IOCP есть только если
>>приложение должно работать с сотнями и тысячами сокетов.
MSS>Основания утверждать такое?
>>И эффективна эта модель ввода-вывода только на мощных серверах.
MSS>А основания утвеждать вот это?
Э. Джонс, Д. Оланд. Программирование в сетях Microsoft Windows. с. 234 (даже найте не поленился )

MSS>Я бы предпочел не иметь ни одного обращения в user32 из серверной софтины. Ну как-то противно оно мне и все. Зачем уровни мешать? GUI — оно GUI, и при чем тут сервера?

Дело в том, что сообщения идут не только от элементов GUI.

MSS>Получается принципиально однонитевое приложение, которое еще и GetMessage должно звать раз в какое-то время. Толку от асинхронности-то? Что несколько сокетов можно сразу обслужить? Ну так для такой картины — одна нитка, много сокетов — есть старый добрый select(), заодно с юниксом совместимый еще один вариант — пользоваться ReadFileEx и потом alertable waits, тоже дело.

Толк от асинхронности такой: в процессе ожидания сообщения загруженность процессора 0%.
... << RSDN@Home 1.1.3 stable silent>>
Re[8]: Аналог ICQ (Клиент-Сервер), как написать?
От: Maxim S. Shatskih Россия  
Дата: 03.06.04 06:26
Оценка:
NF>Э. Джонс, Д. Оланд. Программирование в сетях Microsoft Windows. с. 234 (даже найте не
>поленился )

Этот человек имеет отношение к Редмонду? Заслуживающие доверия источники по Windows — все там

NF>Толк от асинхронности такой: в процессе ожидания сообщения загруженность процессора


То же самое на синхронном блокирующем сокете.
Занимайтесь LoveCraftом, а не WarCraftом!
Re[4]: Аналог ICQ (Клиент-Сервер), как написать?
От: Maxim S. Shatskih Россия  
Дата: 03.06.04 06:27
Оценка: 14 (1)
N>IMHO, Remoting — плохая идея — был бы я дипломным руководителем, я бы с таким
>студентом разговор бы имел короткий. Это то же самое, что стрелять из пушки по
>воробьям.

Нет. Это простейший способ решения задачи, с максимальным реюзом готовых компонент, причем высокого качества (вроде как).

Хотя, если речь о задании студенту — согласен
Занимайтесь LoveCraftом, а не WarCraftом!
Re[9]: Аналог ICQ (Клиент-Сервер), как написать?
От: NoFate Россия  
Дата: 03.06.04 10:21
Оценка:
Здравствуйте, Maxim S. Shatskih, Вы писали:

MSS>Этот человек имеет отношение к Редмонду? Заслуживающие доверия источники по Windows — все там

Оба автора были(а может и сейчас есть) в Microsoft.

MSS>То же самое на синхронном блокирующем сокете.

Согласен, но когда требуется обрабатывать несколько сокетов, то как организовать приём на синхронном блокирующем? Скорее всего, ответишь, что нужно использовать SetEvent, ResetEvent, WaitForSingleObject. Но не проще ли использовать механизм сообщений Windows?
Re[10]: Аналог ICQ (Клиент-Сервер), как написать?
От: Maxim S. Shatskih Россия  
Дата: 03.06.04 12:02
Оценка: +1
NF>Согласен, но когда требуется обрабатывать несколько сокетов

Одной ниткой? Навскидку еще два варианта.

Один вариант — select(), преимущества — портируемость на юниксы (если надо).

Второй вариант (он быстрее, потому как обычно приводит к избежанию лишнего memcpy() внутри AFD) — кинуть по ReadFileEx на каждый, а потом сказать SleepEx(0, TRUE). Позовутся APC.

IOCP для одной нитки действительно бессмысленен, и полностью аналогичен windows message.
Занимайтесь LoveCraftом, а не WarCraftом!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.