Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Последние темы форума

Показать новые сообщения »

Почтовая рассылка

Подписчиков: 11631
Последний выпуск: 19.06.2015

Как написать чат или практика работы с winsock...

Автор: Александр "iCe" Дамбаев

С самого начала хочу сказать, что я не в коем случае не хочу показаться каким-нибудь "отцом" в плане сетевого программирования. Этот чат я написал от нечего делать для себя, а точнее для своей группы :).

Вообще я написал несколько чатов, но расскажу только о первом и последнем, иначе это будет вторая "война и мир" :), хотя я расскажу про способы решения определенных проблем, которые применялись в ранних версиях чата. Вся "серия" этих чатов называется LightChat...

Самый первый мне предложил написать мой брат чисто в целях саморазвития :), в тот момент мы имели только поверхностные знания, касающиеся написания программ для работы сетью. Я делал сервер, а он делал клиента. Мы сразу решили, что сервер не будет встраиваться в программу клиента, хотя бы потому что мы жили далеко друг от друга и очень не хотелось связываться "по-диалапу" для обновления исходного текста и компиляции... Мы соединялись только для проверки их работоспособности. Возникшие проблемы мы решали по телефону, причем иногда это затягивалось на долго :))

Для начинающих, которые, как и мы тогда, ничего не представляют о том как написать сетевую программу, советую воспользоваться C++Bulder'ом - там имеются RAD-компоненты (ServerSocket и ClientSocket) для работы с сокетами (что вам собственно и нужно). Сразу скажу что эти компоненты мне не нравятся, потому что у них обнаружилось пара серьезных глюков, но это сейчас, а тогда - когда появилась первая строчка в окне клиента, меня просто распирало от радости... Эта первая строчка, которая, как я помню состояла только из матов :), означала, что долгие споры и обсуждения по телефону не прошли даром... А тот баг с RAD компонентами заключается в том, что при обработки события ошибки клиента (ClientError, на сколько я помню) сервер начинал выводить сообщение об ошибки на клиенте и выводил его до тех пор, пока не закроешь сервер :) Ну,естественно, клиенты в это время безуспешно пытались общаться с сервером, но ему было уже все равно...

Так вот при написании сервера сразу же стоит решить о том, как сервер будет управлять клиентами, ведь клиент должен иметь ник, IP адрес (хотя для сервера знать IP не обязательно), статус (доступен или нет) и все то, что вы захотите, чтобы сервер знал о клиенте.

Сразу же после этого нужно решить формат пакетов. У нас пакет состоял из Имени отправителя, Имени принимающего, Типа пакета и, собственно, сообщения. Эти "поля" разделялись" определенным символом, который не должен был встречаться при печати. Таким образом - пакет мог иметь переменную длину, что нам казалось большим плюсом. На самом же деле, это оказалось двумя минусами :). Первый минус заключался в том, что поля пакетов (т.е. ник, тип и т.д.) должны были извлекаться вручную - т.е. у вас была строка, которую вы приняли от клиента, из этой строки вам необходимо было извлечь сначала ник отправителя, потом, по достижении того самого спец. символа, извлекался ник получателя, тип, а остальное считалось сообщением. К стати, второй минус тесно связан с первым - у протокола TCP есть свойство соединять слишком маленькие пакеты в один, по идеи это повышает эффективность, но, в таком случае, второй пакет на сервере не распознавался - он был частью сообщения первого - Мы очень часто наблюдали как в выведенном сообщении в конце был полностью следующий пакет, вместе с типом, никами и сообщением :). Чтобы избежать таких неприятностей, ведь не все пакеты содержали сообщения - некоторые были управляющими, мы ввели задержку после отправки пакета,по-моему ок 20мс.

К стати, тип пакета, желательно, должен быть числом, а то я до сих пор улыбаюсь, когда смотрю на двухбайтовую строку Типа, а ведь еще хотели добиться от чата хорошей скорости :)) Единственная забавная возможность, которая была на сервере - это то, что можно было отправлять пакеты от имени любого пользователя, причем не только сообщения, но и управляющие пакеты тоже. Представьте себе, что вы наезжаете на пользователя от имени другого пользователя, а потом его кикаете, от имени этого же пользователя - вот и разберись потом что произошло :))

Ну наверно самое смешное, над чем я сейчас смеюсь больше, чем над самим чатом, было то, что мы хотели его продать :)))

Следующие версии чата я писал в гордом одиночестве, кто знает - может оно и к лучшему.

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

За каждого клиента отвечает отдельный, независимый поток, что также обеспечивает быстродействие.

Все пакеты имеют фиксированную длину и тип теперь - однобайтовое число (char)- это позволило убрать задержки и необходимость "доставать" данные из принятой строки, а также не тратить время на сравнение строк, чтобы узнать тип пакета... Кроме этого при формировании пакета высчитывается его контрольная сумма, при приеме она позволяет определить целостность пакета, то, что теперь пакеты имеют заголовки, позволяет определить подлинность пакета. Если пакет не прошел тест на подлинность или целостность - он игнорируется...

Появилась возможности регистрации ников - данные о регистрации хранятся на сервере в виде двух 4ех байтовых контрольных сумм, при входе пользователя проверяется его ник и если находится такая же контрольная сумма, то его просят ввести пароль, если он вводит не правильный пароль или не вводит его вообще, после 60ти секунд, его кикают :)

Также появилась поддержка банов - при входе проверяется IP адрес пользователя, и если он забанен - соединение закрывается...

Кроме этого имеется возможность оставить сообщение для отсутствующего пользователя. Сообщение должно быть не длиннее размера 1024 байт (это размер данных по умолчанию).

В добавок ко всему - на сервере постоянно имеся поток, который отслеживает возможные атаки. Атаками считаются все соединения, которые не сменяют ник с ника "по-умолчанию" - "default". Если этот поток находит такое подключение, то он его закрывает.

Ну вот, в принципе и все, что можно было рассказать "в двух словах". Если вас это заинтересовало, то можете скачать исходный текст и исполняемые файлы чата LightChat v4.0.1.1 [RAR, 430kb], которые прилагаются к статье. Здесь содержатся мои идеи, которые реализованы при написании чата LightChat. Надеюсь,что после прочтения этой статьи и просмотра исходного кода, вы узнаете что-нибудь новое для себя.

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

Ну и если у вас есть какие-то предложения, а может и замечания, то пишите мне на мыло...

Об остальных аспектах написано в файлах readme.txt, прилагающихся к чату.

Скачать исходник [RAR, 430kb]

Оставить комментарий

Комментарий:
можно использовать BB-коды
Максимальная длина комментария - 4000 символов.
 

Комментарии

1.
8.7K
04 апреля 2006 года
The_Ice
109 / / 04.04.2006
+0 / -1
Мне нравитсяМне не нравится
18 мая 2010, 19:05:31
А я вот сейчас запустил под wine'ом и сижу сам с собой чатюсь, может просто руки такие, не?
2.
61K
12 мая 2010 года
Lyambda
0 / / 12.05.2010
Мне нравитсяМне не нравится
12 мая 2010, 13:34:04
ни фига не работает, виснет
3.
Аноним
Мне нравитсяМне не нравится
23 февраля 2006, 17:16:34
немного напутал ты мух с котлетами ... а так в принципе даже ничего ...
у мну где то валялось нечто похоже на перле и сях ...
некий самописный icq chat (:
поделки и коленописки не рулят (: это я усвоил из нашего с тобой эксперимента ... ((:
теперь если что то делается на продакшн, клепается не за один день/два дня ... (:
удачи!
4.
Аноним
Мне нравитсяМне не нравится
23 февраля 2006, 17:06:08
в общем в локале все оказалось в поряде... хз че с диалапом - я подозреваю пинг :)
5.
Аноним
Мне нравитсяМне не нравится
10 февраля 2006, 23:09:14
хехе....тут я понял,что я совсем тупой!
Придётся осваивать С++ или Delphi.net
Но тема сетевых технологий мне видиться даже во сне!=))
6.
Аноним
Мне нравитсяМне не нравится
23 января 2006, 20:37:52
я дико извеняюсь, но чат, точнее коиент, работает только на локал хосте, как по сети не знаю, а вот по модему, удаленный клиент посему то сам себя отрубает, точнее если отключить одну проверку, он работает нормально, но все же эта проверка должна быть, а с причиной я буду разбираться в ближайшее время. очень не приятно,что это обнаружилось только сейчас, хотя может в сети будет нормально... собираюсь проверить это в ближайшее время, а точнее сегодня днем :) в универе... еще раз извините...
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог