powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Сокетный сервер (многопоточный)
30 сообщений из 30, показаны все 2 страниц
Сокетный сервер (многопоточный)
    #34453810
Фотография Zmeishe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Суть проблемы.
Программа Сервер-приложений валится. (ошибка сегментирования).
Qt + Linux.

Раньше валился чаще - теперь раз в сутки.
Часть проблем я нашёл приведя программу к стандарту С++ явным образом, а не полагаясь на то, что компилятор должен чего-то сам сделать автоматически.
Таким образом ошибка "блуждающая" локализовалась - я её сумел обнаружить и исправить. (об этом я писал, тут, на форуме).

Теперь наставил в контрольных точках вывод действий сервера в консоль cout << "бла-бла-бла" << endl;

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
MyServer::newConnection(int idSocket)
{
  cout << "newConnection begin" << endl;
  ...
  q_thread->start("нормальный приоритет");

  cout << "newConnection end" << endl;
}

MyThread::run()
{
  cout << "thread run begin" << endl;
  ...

  cout << "thread run while" << endl;
  while(!stop) ;

  ...

  cout << "thread run end" << endl;
}



MySocket::slotReadClient()
{   cout << "slotReadClient begin" << endl;
 
   // Разбор запроса клиента

   ...

  // Ответ клиенту

   ...
  cout << "slotReadClient end" << endl;
}

Смотрю в консоль и вижу


> newConnection begin
> newConnection end
> thread run begin
> thread run while
> Ошибка сегментирования

Задним умом понимаю до

MySocket::slotReadClient begin

он не дошёл, а больше программа ничего не делает. После старта потока она должна принять запрос клиента.
Спрашивается - а В ГДЕ она вывалилась?
...
Рейтинг: 0 / 0
Сокетный сервер (многопоточный)
    #34453828
Фотография Gluk (Kazan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ээээ логирование канешна карашо, а где код ???
...
Рейтинг: 0 / 0
Сокетный сервер (многопоточный)
    #34453851
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Так другой поток, может, валит?
...
Рейтинг: 0 / 0
Сокетный сервер (многопоточный)
    #34453873
Фотография Zmeishe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Какой именно?

Думаю, для начала интересен этот

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
MyServer::newConnection(int idSocket)
{
  MyThread *q_thread = new MyThread(idSocket);

  q_thread->start("нормальный приоритет");
}


MyThread::run()
{
   MySocket *socket = new MySocket();

   socket->init(idSocket);

    while(!stop) ;

    delete socket; 
}

MySocket::init(int idSocket)
{
  ...
  setSocket(idSocket);
}
...
Рейтинг: 0 / 0
Сокетный сервер (многопоточный)
    #34453895
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ZmeisheКакой именно?

Думаю, для начала интересен этот

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
MyServer::newConnection(int idSocket)
{
  MyThread *q_thread = new MyThread(idSocket);

  q_thread->start("нормальный приоритет");
}


MyThread::run()
{
   MySocket *socket = new MySocket();

   socket->init(idSocket);

    while(!stop) ;

    delete socket; 
}

MySocket::init(int idSocket)
{
  ...
  setSocket(idSocket);
}


Не знаю, что у тебя за операционка, но у меня (ASP10) такая конструкция запросто может систему подвесить.

Поток у тебя, конечно, оригинальный. Зачем тебе пустой поток?

Этим кодом ты ничего не показал. Вызов каких-то твоих функций.
...
Рейтинг: 0 / 0
Сокетный сервер (многопоточный)
    #34453943
Фотография Zmeishe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторНе знаю, что у тебя за операционка, но у меня (ASP10) такая конструкция запросто может систему подвесить.

Поток у тебя, конечно, оригинальный. Зачем тебе пустой поток?

Этим кодом ты ничего не показал. Вызов каких-то твоих функций.
Suse не виснет, Fedora не виснет, ASP не проверял.


Опишу свою сакральную мысль, а ВЫ раскритикуйте.

SoketServer слушает порт и ждёт какого-нибудь клиента
На появление клиента создаёт обект класса - поток
В потоке создаётся объект класса - клиентский сокет
В сокете объект класса - модуль данных

Не знаю насколько это логично, но без потока тяжёлый SQL запрос ждали все клиенты - теперь не ждут.

Делал по другому - создавал клиентский сокет не в потоке - тормоза.

Подскажите другую схему.
...
Рейтинг: 0 / 0
Сокетный сервер (многопоточный)
    #34454084
kolobok0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Zmeishe...Смотрю в консоль и вижу
> newConnection begin
> newConnection end
> thread run begin
> thread run while
> Ошибка сегментирования

...


предлагаю начать с грамотного подъёма ниток... задайтесь вопросом - а нахрен подымать нитку, если Вампох(простите) пофигу её судьба ? поднялась, не поднялась - а, летим дальше...Предлагаю нафик не подымать - Вам же ВСЁ РАВНО !!!


Или по другому - на лицо типичная ошибка, которая будет плавающей от нагрузки на Вашу систему (Ваша система будет по РАЗНОМУ работать, в зависимости от нагрузки - что в принцепе бред..опустим конэшно самоподстраивающиеся алгоритмы - не о них речь...)...

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

с уважением
(круглый)
...
Рейтинг: 0 / 0
Сокетный сервер (многопоточный)
    #34454547
A. Fig Lee
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
где pthread_join()
и ваще - кто stop значение устанавливает?
надо бы conditional variable если разные потоки
...
Рейтинг: 0 / 0
Сокетный сервер (многопоточный)
    #34454799
Фотография Gluk (Kazan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ZmeisheКакой именно?


Который кладет процесс ;)
...
Рейтинг: 0 / 0
Сокетный сервер (многопоточный)
    #34454913
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Zmeishe авторНе знаю, что у тебя за операционка, но у меня (ASP10) такая конструкция запросто может систему подвесить.

Поток у тебя, конечно, оригинальный. Зачем тебе пустой поток?

Этим кодом ты ничего не показал. Вызов каких-то твоих функций.
Suse не виснет, Fedora не виснет, ASP не проверял.


Опишу свою сакральную мысль, а ВЫ раскритикуйте.

SoketServer слушает порт и ждёт какого-нибудь клиента
На появление клиента создаёт обект класса - поток
В потоке создаётся объект класса - клиентский сокет
В сокете объект класса - модуль данных

Не знаю насколько это логично, но без потока тяжёлый SQL запрос ждали все клиенты - теперь не ждут.

Делал по другому - создавал клиентский сокет не в потоке - тормоза.

Подскажите другую схему.


По вышеописанной схеме, вместа while (!stop) ;, логично было бы поставить recv(). Ваша схема не понятна.
...
Рейтинг: 0 / 0
Сокетный сервер (многопоточный)
    #34454919
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как опредилить какой поток вызывает крах системы решается путем установки обработчика сигнала. Недавно обсуждали.
...
Рейтинг: 0 / 0
Сокетный сервер (многопоточный)
    #34455042
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AkhКак опредилить какой поток вызывает крах системы решается путем установки обработчика сигнала. Недавно обсуждали.

тынц
...
Рейтинг: 0 / 0
Сокетный сервер (многопоточный)
    #34455103
Фотография Zmeishe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AkhПо вышеописанной схеме, вместа while (!stop) ;, логично было бы поставить recv(). Ваша схема не понятна.
recv() это что и в где? В библиотеке Qt оно есть?

Схема рабоче-крестьянская. Проста как топор.
Поясню:
Многопоточностью начал заниматься недавно - много просто не знаю.
Обратился к книгам.
Прочитал следущее:
Приложение есть процесс - главный процесс, но для операционки просто поток - отдельный поток.
Если приложение многопользовательское, то чтобы клиенты не ждали друг друга имеет смысл распараллелить их работу.
Лобовое решение - запускать столько серверных приложений сколько клиентов. Но сервер на сокетах начнёт орать, что порт занят. Т.е. каждому клиенту ещё и свой порт выделять.
Приличное решение - запускать в отдельной области памяти нечто, каждому клиенту.
Многопоточность, типа, и есть то самое решение. Необходимо только унаследовать класс от QThread и перекрыть виртуальную функцию run(). Что я, собственно, и сделал.

Вот я в функции потока run() создаю объект, функции которого должны выполняться в отдельной области памяти. Привязываю его к событиям класса QServerSocket и while(!stop);
Когда QServerSocket получает сигнал об отключении клиента он для этого sender(), который socket, вызывает stop() соответствующего потока. run() заканчивает работу.
Скорость при этом - бешеная. Независимо 1 клиент или 10.

Я понимаю, что это топорная работа. И система показывает, что мой процесс жрёт 98.2% CPU.
При этом сама система не тормозит.

Я переделал всё это иначе.
стартую поток только когда от клиента пришли данные и в функции потока run() вызываю свою функцию пересылки SQL запроса к БД и потом формирую ответ клиенту. После чего поток заканчивает работу, до тех пор пока я снова не вызову потоку start() на очередной запрос клиента.
Теперь система показывает, что мой процесс жрёт 0.3-0.7% CPU и только во время обращения к БД и отправки ответа клиенту - потом 0.0 %CPU.
Это ещё более топорная работа т.к. start() потока занимает какое-то время и клиент получате данные паузами.
Если есть DataSet - мастер и у него много DataSet`ов - деталей - каждая деталь открывается с паузами в 1 сек.
Это оч. долго. В первом варианте с while(!stop) их вообще не было.

На большее, пока, фантации не хватает.
Мне собственно нужна грамотная схема связей между MyServerSocket, MySocket, MyThread и чего там в run(), если по уму. Чисто концептуально - мысль понять, остальное сам сделаю.
...
Рейтинг: 0 / 0
Сокетный сервер (многопоточный)
    #34455191
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Zmeishe AkhПо вышеописанной схеме, вместа while (!stop) ;, логично было бы поставить recv(). Ваша схема не понятна.
recv() это что и в где? В библиотеке Qt оно есть?

Схема рабоче-крестьянская. Проста как топор.
Поясню:
...

Понятно. Я считал, что схема клиент-поток. Оказывается задача-поток. Тогда логично было бы сделать вместо while(!stop) ; - синхронное обращение к БД. А у вас как?
...
Рейтинг: 0 / 0
Сокетный сервер (многопоточный)
    #34457010
aak__
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
просто замечание.

имхо, в подобных циклах

Код: plaintext
1.
while(!stop) ;


лучше ставить

Код: plaintext
1.
2.
while(!stop) 
    Sleep( 100 );
...
Рейтинг: 0 / 0
Сокетный сервер (многопоточный)
    #34457218
Фотография Zmeishe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
aak__просто замечание.

имхо, в подобных циклах

Код: plaintext
1.
while(!stop) ;


лучше ставить

Код: plaintext
1.
2.
while(!stop) 
    Sleep( 100 );


БОЛЬШОЕ ЧЕЛОВЕЧЕСКОЕ СПАСИБО!

Сделал так
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
...
sockThread->start(QThread::NormalPriority); 
sleep( 1 ); // 1 sec
...

...
while(!stop)
  msleep( 100 ); // 0.1 сек
...

Полёт нормальный.
Теперь не жрёт 98% CPU
Теперь всё как у взрослых - CPU отжирает постепенно, по мере возрастания нагрузки и потом отпускает до 0.0%
...
Рейтинг: 0 / 0
Сокетный сервер (многопоточный)
    #34457270
aak__
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
да.
есть такая фича в performance tuning ))))
...
Рейтинг: 0 / 0
Сокетный сервер (многопоточный)
    #34458174
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Zmeishe
Полёт нормальный.
Теперь не жрёт 98% CPU
Теперь всё как у взрослых - CPU отжирает постепенно, по мере возрастания нагрузки и потом отпускает до 0.0%

Ты писал, что у тебя Теперь система показывает, что мой процесс жрёт 0.3-0.7% CPU и только во время обращения к БД и отправки ответа клиенту - потом 0.0 %CPU. итак все нормально.

А по поводу, расстановки sleep-ов - ты просто избегаешь ошибку, а не исправляешь.
...
Рейтинг: 0 / 0
Сокетный сервер (многопоточный)
    #34458245
Фотография Zmeishe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я также писАл:

авторЭто ещё более топорная работа т.к. start() потока занимает какое-то время и клиент получат данные паузами.
Если есть DataSet - мастер и у него много DataSet`ов - деталей - каждая деталь открывается с паузами в 1 сек.
Это оч. долго. В первом варианте с while(!stop) их вообще не было

А со sleep`ом, я остался на первом варианте, когда не одна функция некоего класса зашита в run(), а весь объект со всей байдой. Скорость оч. комфортная и никаких пауз между запросами.
Паузы возникали либо на thread->start(), thread->stop() и опять thread->start(). Либо на mutex.lock(), mutex.unlock(). Со sleep`ом ничего этого нет, есть только скорость.


AkhА по поводу, расстановки sleep-ов - ты просто избегаешь ошибку, а не исправляешь.
Может быть. После такой сильной разницы со sleep`ом и без, пока рано что-либо утверждать.
Подождём недельку. Если ежесуточных падений больше не будет, будем считать, что ошибки нет.

Я думаю while(!stop); 98% CPU в одной нити не давали продыху другим нитям, что-либо делать ещё на системном уровне, вот оно и падало между thread->start() и приходом данных в канал. Ни то ни другое от меня не зависят, они системные, а системе как раз и не было продыху- типа занята.

Будем посмотреть недельку.
...
Рейтинг: 0 / 0
Сокетный сервер (многопоточный)
    #34458302
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Zmeishe

AkhА по поводу, расстановки sleep-ов - ты просто избегаешь ошибку, а не исправляешь.
Может быть. После такой сильной разницы со sleep`ом и без, пока рано что-либо утверждать.
Подождём недельку. Если ежесуточных падений больше не будет, будем считать, что ошибки нет.

Я думаю while(!stop); 98% CPU в одной нити не давали продыху другим нитям, что-либо делать ещё на системном уровне, вот оно и падало между thread->start() и приходом данных в канал. Ни то ни другое от меня не зависят, они системные, а системе как раз и не было продыху- типа занята.

Будем посмотреть недельку.

Системе продых дается. Иначе у тебя все бы повисло на мертво.

Я не призываю тебя не пользоваться sleep() - наоборот, это правельный подход. Но у тебя был хороший шанс отладится, а ты его упускаешь.

Хочешь, копи глюки дальше. Когда напишешь большую программу, в которой будет несколько таких глюков, то ты потеряешь над ней контроль, а отладить ее будет на порядки сложнее, чем по одиночке.
...
Рейтинг: 0 / 0
Сокетный сервер (многопоточный)
    #34458380
Карабас Барабас
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Zmeishewhile(!stop); этта, может у тебя кулер на проце уже старенький, да и просто перегревается проц, когда долго идет 100-процентная загрузка ?
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Сокетный сервер (многопоточный)
    #34458426
Фотография Zmeishe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Akh Но у тебя был хороший шанс отладится
Согласен.


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

Если бы косяк был в тексте программы - его рано или поздно через дебаггер увидеть можно.
Собственно до этого я так и сделал - локализовав ошибку, заставил её проявляться постоянно, а не случайно, и на конкретные действия.
А тут ошибка во время коннекта клиента, а в коннекте между стартом нити и готовностью принимать данные в сокете. У меня на эти действия ни строчки кода - это либо в библиотеке Qt, либо в системе, либо у меня чего-то отсутствует (напр. sleep()). А как дебаггер покажет чего отсутствует? На нет и суда нет.
Можно, конечно, придумать способ измерения нагрузки на другие нити в то время, когда происходит очередной коннект, ну а дальше что?
...
Рейтинг: 0 / 0
Сокетный сервер (многопоточный)
    #34458440
Фотография Zmeishe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Карабас Барабасда и просто перегревается проц, когда долго идет 100-процентная загрузка
В серверной как в холодильнике - там кондиционер арктический тропик создаёт.
10 мин и уже про тулупчик заячий вспоминаешь.
...
Рейтинг: 0 / 0
Сокетный сервер (многопоточный)
    #34458468
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ZmeisheА тут ошибка во время коннекта клиента, а в коннекте между стартом нити и готовностью принимать данные в сокете.

После создания нового серверного сокета для клиента, он сразу готов к приему данных.
...
Рейтинг: 0 / 0
Сокетный сервер (многопоточный)
    #34458525
Фотография Zmeishe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Akhсразу готов к приему данных.
Он то готов, но событие о прибытии данных ещё не наступило для программы, а функция thread->start() уже отработала. Программа уже скомандовала старт нити и ждёт, когда же нить фактически стартует и ждёт прихода запроса от клиента. И тут ошибка - она В ГДЕ? Между чем и чем?
...
Рейтинг: 0 / 0
Сокетный сервер (многопоточный)
    #34458589
Akh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Zmeishe Akhсразу готов к приему данных.
Он то готов, но событие о прибытии данных ещё не наступило для программы, а функция thread->start() уже отработала. Программа уже скомандовала старт нити и ждёт, когда же нить фактически стартует и ждёт прихода запроса от клиента. И тут ошибка - она В ГДЕ? Между чем и чем?

Событие о прибытии данных? У тебя асинхронная передача данных?

Вот по этому событию и создавай свою нить.

Я бы создовал по коннекшену и в нем бы получал событие прихода данных.
...
Рейтинг: 0 / 0
Сокетный сервер (многопоточный)
    #34458596
Фотография Zmeishe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
К тому же, коннектов может быть много и без этой ошибки, потом часть клиентов отконнектились, потом другая часть начинает коннектиться и на очередной коннект ЭТА ОШИБКА.
А иногда сразу на первом коннекте отваливается. Снова запускаю и опять куча коннектов спокойно работают.
Со sleep`ом уже со вчерашнего вечера всё нормально.
Вот и предлагаю понаблюдать неделю 7x24, а потом сделаем выводы.
...
Рейтинг: 0 / 0
Сокетный сервер (многопоточный)
    #34458609
Фотография Zmeishe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AkhСобытие о прибытии данных? У тебя асинхронная передача данных?

Вот по этому событию и создавай свою нить.

Я бы создовал по коннекшену и в нем бы получал событие прихода данных.
Я по коннекшену создаю.
Если на каждое событие о приходе данных создавать - тормоза необычайные.
...
Рейтинг: 0 / 0
Сокетный сервер (многопоточный)
    #34458612
Карабас Барабас
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ZmeisheВ серверной как в холодильнике если тепловой контакт кулера с процом плохой, то и арктика не поможет
Posted via ActualForum NNTP Server 1.4
...
Рейтинг: 0 / 0
Сокетный сервер (многопоточный)
    #34475002
Фотография Zmeishe
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну вот.
7х24 прошли. Все работает стабильно. Без вздохов и бздыхов.
Но вот в чём фишка, Akh был прав. sleep() не решил проблему, а загнал её куда-то так, что она за 7x24 ни разу не проявилась.
Вылезла она только тогда, когда я добавил в один класс новую функцию.
Программа стала неработостпособной вовсе. Т.е. изменился размер класса и чего-то где-то сместилось. Некий указатель стал указывать на адрес, в котором вдруг ничего нет, а вообще-то было. И никаких delete не вызывалось, так как delete на этот указатель только в деструкторе родительского класса.
Вот код.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
QIBDataModule::QIBDataModule(const QString& iniKeyEntry): QRemoteIBDataModule()
{
 QString s_key;   
 QSettings settings;
 settings.beginGroup("/settings-srv-sock");

 ... 
 s_key = iniKeyEntry + QString("/DBServer");
 IBDb->DatabaseName = settings.readEntry(s_key, "Ib-Server");

 s_key = iniKeyEntry + QString("/DBName");
 IBDb->DatabaseName += QString(":") + settings.readEntry(s_key, "/base/test.ib");  

 // функция  settings.readEntry возвращала лажу т.к. s_key уже лажовый.
 // при этом каким-то образом портился указатель IBDb.

 connect(IBDb, SIGNAL(sendBeforeConnect()), SLOT(slotBeforeConnect()));
} 


void QIBDataModule::slotBeforeConnect()
{
   QIBDatabase *db;
   QString User;
   
    // Вот тут указатель уже испорчен, а должен  быть IBDb
    db = (QIBDatabase*) sender();
   
    // При первом же обращении "Ошибка сегментирования"
   User = db->getUsername(); 

   ...
}


Код: plaintext
1.
2.
3.
4.
// Решил проблему выкидыванием &
QIBDataModule::QIBDataModule(const QString iniKeyEntry): QRemoteIBDataModule()
{
}

Не случайно меня интересовал Сакральный смысл передачи по ссылке &

Интересно, я теперь решил проблему или загнал ещё глубже чем sleep()?
...
Рейтинг: 0 / 0
30 сообщений из 30, показаны все 2 страниц
Форумы / C++ [игнор отключен] [закрыт для гостей] / Сокетный сервер (многопоточный)
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]