|
PureBasic Мощный кросс-платформенный язык среднего уровня на основе BASIC. Подходит для решения широкого круга задач. |
12.12.2012, 17:33
|
#1
|
Разработчик
Регистрация: 27.06.2009
Адрес: Рязань-Москва
Сообщений: 471
Написано 401 полезных сообщений (для 1,072 пользователей)
|
Пример сервера на PureBasic
Пока допиливаю свои ммо-поделки, решил поделиться небольшими наработками по серверу на пурике.
В общем, сервер, работает в трех потоках, использует БД SQLite. В аттаче архив с иходниками и exe сервера, а также тестового клиента.
Основной поток (MainLoop) обрабатывает принятые пакеты, формирует пакеты на отправку через два списка. Второй поток добавляет принятые сервером данные в первый список, а третий поток считывает данные из второго списка и отправляет нужным клиентам.
Код сдобрен комментами, так что проблем возникнуть не должно.
Проверить работу можно через тест-клиент, который написан на блитце. При старте клиент сразу сам подключается к серверу на порт 9105 (выдаст MAV, если сервер не запущен или недоступен). Он работает в "ручном" режиме - то есть нужно набирать пакет с клавиатуры. Формат пакета: "[Команда]#[Данные]#...#[Данные]#", Где # - разделитель Chr(13) - добавляется по клавише F1 клиента. Enter - отправить пакет.
Команды:
Login#Name#Pass#version#
Register#Name#Pass#version#e-mail#
Move#X#Y#
Каждую команду обрабатывает отдельная процедура, то есть легко добавить на сервер новые команды.
В общем, может кому-то пригодится Также просьба похаять код, подсказать что можно улучшить/переделать - например формат и метод обработки пакетов.
|
(Offline)
|
|
Эти 6 пользователя(ей) сказали Спасибо DStalk за это полезное сообщение:
|
|
13.12.2012, 09:12
|
#2
|
Разработчик
Регистрация: 08.08.2011
Сообщений: 505
Написано 191 полезных сообщений (для 369 пользователей)
|
Ответ: Пример сервера на PureBasic
Автору респект не каждый день такое выкладывают. Давно хотел разобраться в серверной части, буду учиться на примере твоего кода. По коду ничего сказать не могу, ибо ничерта не смыслю в серверах, но хотел бы сказать отдельное спасибо за качественные комменты, буду разбираться на досуге
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
27.10.2013, 00:06
|
#3
|
ПроЭктировщик
Регистрация: 14.01.2012
Адрес: Зеленоград
Сообщений: 192
Написано 5 полезных сообщений (для 9 пользователей)
|
Ответ: Пример сервера на PureBasic
А как соединяться? Он работает только для своего компа, а с другим компом даже через hamachi не удалось соединиться
__________________
|
(Offline)
|
|
27.10.2013, 11:01
|
#4
|
Разработчик
Регистрация: 27.06.2009
Адрес: Рязань-Москва
Сообщений: 471
Написано 401 полезных сообщений (для 1,072 пользователей)
|
Ответ: Пример сервера на PureBasic
Возможно порт закрыт? Ограничений то нет никаких, в клиенте просто вместо localhost нужно указать ip-адрес, где сервер крутится.
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
27.10.2013, 11:47
|
#5
|
ПроЭктировщик
Регистрация: 14.01.2012
Адрес: Зеленоград
Сообщений: 192
Написано 5 полезных сообщений (для 9 пользователей)
|
Ответ: Пример сервера на PureBasic
Спасибо! Работает
__________________
|
(Offline)
|
|
27.10.2013, 16:53
|
#6
|
ПроЭктировщик
Регистрация: 14.01.2012
Адрес: Зеленоград
Сообщений: 192
Написано 5 полезных сообщений (для 9 пользователей)
|
Ответ: Пример сервера на PureBasic
В коде есть переменные tmpData и tmpSpecial. Что такое tmp? А то я уже начинаю путаться.
__________________
|
(Offline)
|
|
27.10.2013, 17:50
|
#7
|
Разработчик
Регистрация: 27.06.2009
Адрес: Рязань-Москва
Сообщений: 471
Написано 401 полезных сообщений (для 1,072 пользователей)
|
Ответ: Пример сервера на PureBasic
tmp - temp, временная переменная я просто их так обозвал.
Сразу после считывания данных из очереди (Queue), элемент списка очереди удаляется (чтобы не держать mutex заблокированным), а данные из него сохраняются как раз во временных переменных и далее обрабатываются.
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
27.10.2013, 20:02
|
#8
|
ПроЭктировщик
Регистрация: 14.01.2012
Адрес: Зеленоград
Сообщений: 192
Написано 5 полезных сообщений (для 9 пользователей)
|
Ответ: Пример сервера на PureBasic
Обязательно ли использовать базу данных, или можно записывать в простой текстовый файл?
__________________
|
(Offline)
|
|
27.10.2013, 20:47
|
#9
|
Разработчик
Регистрация: 27.06.2009
Адрес: Рязань-Москва
Сообщений: 471
Написано 401 полезных сообщений (для 1,072 пользователей)
|
Ответ: Пример сервера на PureBasic
Конечно можно - база данных нужна для более быстрого поиска, выборки по определенным полям и т.п., в общем оптимальней...
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
27.10.2013, 21:45
|
#10
|
ПроЭктировщик
Регистрация: 14.01.2012
Адрес: Зеленоград
Сообщений: 192
Написано 5 полезных сообщений (для 9 пользователей)
|
Ответ: Пример сервера на PureBasic
Интересно, Delay(10) в данном коде значительно ускоряет программу. С чем это связано?
If CreateNetworkServer(Ip,Port)
PrintN("The server has been created!")
If CreateThread(@ReceiveTCPdata(),0) = 1
PrintN("The receive thread has been started!")
Else
PrintN("The receive thread failed!")
Delay(2000)
End
EndIf
Repeat
If TrySemaphore(SemaphoreIn) <> 0
LockMutex(MutexIn)
FirstElement(QueueIn())
TempFlag.i = QueueIn()\Flag
TCPclientID = QueueIn()\TCPclientID
TempData.s = QueueIn()\TCPdata
UnlockMutex(MutexIn)
DeleteElement(QueueIn())
Select TempFlag
Case 1;Новое подключение
connectMap(Str(TCPclientID))\Packet=""
PrintN("New connection: "+Str(TCPclientID))
Case 2;Дисконнект
PrintN("Disconnected: "+Str(TCPclientID))
DeleteMapElement(ConnectMap(),Str(TCPclientID))
EndSelect
EndIf
Delay(10)
Until Inkey() = Chr(27)
CloseNetworkServer(Ip)
Else
PrintN("The server creation failed!")
Delay(2000)
End
EndIf
__________________
|
(Offline)
|
|
27.10.2013, 22:05
|
#11
|
Злобный Админ
Регистрация: 04.09.2005
Сообщений: 5,926
Написано 3,415 полезных сообщений (для 9,330 пользователей)
|
Ответ: Пример сервера на PureBasic
В потенциально бесконечных циклах, без delay произойдёт явление похожее на зависание, когда программа будет потреблять 100% процессорных ресурсов. В результате система может неиметь достаточных ресурсов чтобы выполнить свою часть работы, результатов работы которйо программа и ожидает таким способом.
Посути команда Delay(10) даёт немного времени системе для выполнения своих дел. Хотя я бы в таком цикле поставил время отдаваемое системе побольше, например 100.
__________________
|
(Offline)
|
|
Эти 3 пользователя(ей) сказали Спасибо SBJoker за это полезное сообщение:
|
|
27.10.2013, 23:26
|
#12
|
Зануда с интернетом
Регистрация: 04.09.2005
Сообщений: 14,014
Написано 6,798 полезных сообщений (для 20,935 пользователей)
|
Ответ: Пример сервера на PureBasic
Кроме того, если получение данных от сетевого интерфейса идёт в другом потоке, то такая спин-блокировка (отсутствие delay на одноядерном камне) может привести к ситуации дефицита ресурсов процессора для задачи получения данных, что в итоге отобразится на основном потоке, который с этими данными и работает (по сути, Джокер это и написал).
__________________
http://nabatchikov.com
Мир нужно делать лучше и чище. Иначе, зачем мы живем? tormoz
А я растила сына на преданьях
о принцах, троллях, потайных свиданьях,
погонях, похищениях невест.
Да кто же знал, что сказка душу съест?
|
(Offline)
|
|
Сообщение было полезно следующим пользователям:
|
|
28.10.2013, 01:53
|
#13
|
Нуждающийся
Регистрация: 23.05.2007
Сообщений: 95
Написано 34 полезных сообщений (для 53 пользователей)
|
Ответ: Пример сервера на PureBasic
В коде есть несколько потенциальных "глючных" мест.
If CreateThread(@ReceiveTCPdata(),0) = 1
|
С чего вдруг функции CreateThread() возвращать 1?
В справке ясно написано.
Возвращаемое значение.
Номер созданного потока, или ноль если новый поток создать невозможно. Этот номер необходим, если вы хотите контролировать поток с помощью других функций этой библиотеки.
|
Номер потока не обязательно равен числу 1. В итоге даже при успешном создании потока, прога завершится с сообщением об ошибке.
UnlockMutex(MutexIn)
DeleteElement(QueueIn())
|
Почему сначала расблокируется мьютекс, а затем удаляется элемент? Должно быть наоборот. Иначе возможна ситуация что будет удален не тот элемент, если другой поток обратится в списку и изменит текущий элемент.
|
(Offline)
|
|
Эти 2 пользователя(ей) сказали Спасибо Пётр за это полезное сообщение:
|
|
28.10.2013, 07:02
|
#14
|
ПроЭктировщик
Регистрация: 14.01.2012
Адрес: Зеленоград
Сообщений: 192
Написано 5 полезных сообщений (для 9 пользователей)
|
Ответ: Пример сервера на PureBasic
Спасибо, учту
__________________
|
(Offline)
|
|
30.10.2013, 20:36
|
#15
|
ПроЭктировщик
Регистрация: 14.01.2012
Адрес: Зеленоград
Сообщений: 192
Написано 5 полезных сообщений (для 9 пользователей)
|
Ответ: Пример сервера на PureBasic
Каким образом мы используем ASCII коды 31 и 10, и как они оказываются в пакетах, принятых от клиента?
__________________
|
(Offline)
|
|
Ваши права в разделе
|
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 07:51.
|