Название: TCP. отключение от сервера. Отправлено: meandnano от Май 01, 2010, 16:40 здравствуйте. такой вопрос:
Есть клиент-сервеное приложение (TCP). При отключении клиента от сервера мне неоюходимо знать, какой именно клиент отключился. Если клиент уходит, посредством нажатия специально обученой кнопки, тогда никаких проблем - программа сначала отсылает серверу соответствующее сообщение. Но необходимо обработать уход клиента и при случайном разрыве. Пытался соеденить disconnected() клиента cо слотом в котором делается QTcpSocket *X = (QTcpSocket*) sender(); - но так не прокатывает, при отключении сервер вылетает с сегфолтом. Собственно нужно это за тем, чтобы удалить соответствующий элемент из контейнера с клиентами QVector<QTcpSocket*> и оповестить всех остальных клиентов. Достаточно знать хотя бы socketDescriptor клиента. Есть ли варианты? Название: Re: TCP. отключение от сервера. Отправлено: BRE от Май 01, 2010, 16:54 Есть ли варианты? Покажи, что делается в слоте, который подключен к disconnected.Думаю ты просто разрушаешь объект delete, если это так, то так делать нельзя. В общем покажи, что бы мы не гадали. ;) Название: Re: TCP. отключение от сервера. Отправлено: garryHotDog от Май 01, 2010, 18:12 попробуй обрабатывать сигнал сокета
Цитировать void QAbstractSocket::stateChanged ( QAbstractSocket::SocketState socketState ) [signal] и при отключении сокета посылать новый сигнал!например: Код:
Название: Re: TCP. отключение от сервера. Отправлено: meandnano от Май 01, 2010, 18:37 BRE
вот соединение Код: void cserver::newconn(){ еще была строка: connect(Client,SIGNAL(disconnected()),Client,SLOT(deleteLater())); но убрал по случаю соединения с disconn(); Код: void cserver::disconn(){ delete sender(); ? garryHotDog спасибо, сейчас буду пробовать Название: Re: TCP. отключение от сервера. Отправлено: BRE от Май 01, 2010, 18:51 Попробуй так:
Код
Название: Re: TCP. отключение от сервера. Отправлено: meandnano от Май 01, 2010, 19:02 Попробуй так: Код
попробую garryHotDog компилятор ругается на регистрацию типа - заявляет Цитировать error: too few template-parameter-lists хотя запись соответствует мануалуНазвание: Re: TCP. отключение от сервера. Отправлено: BRE от Май 01, 2010, 19:05 попробую Главное все же это: :) Код
Название: Re: TCP. отключение от сервера. Отправлено: meandnano от Май 01, 2010, 19:17 BRE
вести с фонтов: в disconn() обоими способами: 1) QTcpSocket *Client = (QTcpSocket*) sender(); 2) QTcpSocket *Client = qobject_cast<QTcpSocket*>( sender() ); и Client->deleteLater() на конце все проходит без ошибок, НО не правильно - отладка показывает, что Client->socketDescriptor()=-1 Название: Re: TCP. отключение от сервера. Отправлено: garryHotDog от Май 01, 2010, 19:38 у меня регистрация вынесена в конструктор класса!
Название: Re: TCP. отключение от сервера. Отправлено: BRE от Май 01, 2010, 19:46 все проходит без ошибок, НО не правильно - отладка показывает, что Client->socketDescriptor()=-1 А что ты ожидаешь там увидеть, при приеме сигнала disconnected. Сокет уже закрыт. Название: Re: TCP. отключение от сервера. Отправлено: meandnano от Май 01, 2010, 20:13 А что ты ожидаешь там увидеть, при приеме сигнала disconnected. Сокет уже закрыт. ну я предполагал, что так и будет, но вся соль то как раз в том, что мне надо socketID получить от уходящего клиента. garryHotDog сделал так: Код
правильно ли? Client->socketDescroptor() возвращает -1 Название: Re: TCP. отключение от сервера. Отправлено: garryHotDog от Май 01, 2010, 22:41 Код ты здесь корректно получаешь указатель на Client ? попробуем добавить Код
а получить другие параметры от Client можно? например адрес или порт?? цитатка из ассиста Цитировать The socket descriptor is not available when QAbstractSocket is in UnconnectedState. Название: Re: TCP. отключение от сервера. Отправлено: meandnano от Май 01, 2010, 22:49 В if( Client ) заходит, но id = -1
Название: Re: TCP. отключение от сервера. Отправлено: garryHotDog от Май 01, 2010, 22:50 Цитировать а получить другие параметры от Client можно? например адрес или порт?? Название: Re: TCP. отключение от сервера. Отправлено: meandnano от Май 01, 2010, 23:03 у меня все на socketID завязано.
загвоздка в отм, что у меня есть QVector<QTcpSocket*> - где все они лежат. сделано это было с целью отправлять сообщения всем или только некоторым, путем перебора элементов в векторе. Название: Re: TCP. отключение от сервера. Отправлено: garryHotDog от Май 01, 2010, 23:11 что то я не понял до конца!?
как я понимаю есть 2 варианта обработки подключения к серверу 1. обрабатывать сигнал сервера newConnection() и получать указатель на сокет с помощью nextPendingConnection () 2. переписать виртуальную функцию сервера incomingConnection(int), тем самым будем иметь дескриптор сокета. Лично я использую 2, так как вывожу обработки клиента в поток.....и хранить список подключенных можно в след виде: Код , где int - дескриптор сокета.....это я к тому что ты можешь добавить слот к клиенту, который по отключению будет слать свой дескриптор серверу, а тот в свою очередь удалять его из списка (именно списка!!! - потому что добавление и удаление в нем быстрее чем в векторе)...вот как то так Название: Re: TCP. отключение от сервера. Отправлено: garryHotDog от Май 01, 2010, 23:37 только что накидал небольшую прогу - пробовал получить socketDesck после отключения сокета - выдавал -1....единственное что могу посоветовать хранить не дескриптор сокета ,а например ip+port:
Код
когда клиент отключается он посылает сигнал - disconnected(), лови этот сигнал у удаляй его данные из списка. Название: Re: TCP. отключение от сервера. Отправлено: meandnano от Май 02, 2010, 00:08 я использую вариант 1 (дескриптов сокеты и так получишь). вопрос, как реализовать рассылку сообщений все клиентам, имея только их ip+port.
я вот думаю, может как-то организовать таймер на клиенте, который будет каждые n секунд посылать сообщения серверу - но пока хз как это устроить. Название: Re: TCP. отключение от сервера. Отправлено: garryHotDog от Май 02, 2010, 09:41 если клиент будет слать сообщения серваку - это будет лишней нагрузкой на сеть!! Если тебя это устроит?? а как тебе вариант сделать на серваке таймер, который через n секунд будет проверять список(вектор) с клиентами и смотрел кто отключился? этот вариант менее ресурсоемкий....можешь сделать данную проверку когда клиент шлет сигнал disconnected()!
p.s. А чем тебя не устроил вариант ?? у меня он работает! Цитировать когда клиент отключается он посылает сигнал - disconnected(), лови этот сигнал у удаляй его данные из списка. Название: Re: TCP. отключение от сервера. Отправлено: meandnano от Май 02, 2010, 17:21 а как тебе вариант сделать на серваке таймер, который через n секунд будет проверять список(вектор) с клиентами и смотрел кто отключился? этот вариант менее ресурсоемкий....можешь сделать данную проверку когда клиент шлет сигнал disconnected()! такой вариант меня очень даже устроит, единственный вопрос - как проверить подключен ли клиент из моего списка (вектора) к моему серверу? данные о нем вроде как в полной мере сохранены (т.е. например socketID соответствует тому, что был выдан сервером при коннекте). Название: Re: TCP. отключение от сервера. Отправлено: garryHotDog от Май 02, 2010, 18:47 Цитировать как проверить подключен ли клиент из моего списка (вектора) к моему серверу? ты при подключении будешь добавлять в список данные о клиенте, а при его дисконнекте будешь удалять!!!Название: Re: TCP. отключение от сервера. Отправлено: meandnano от Май 02, 2010, 23:40 остановился на работе с айпишником вместо socketID. все работает. всем спасибо
Название: Re: TCP. отключение от сервера. Отправлено: garryHotDog от Май 03, 2010, 00:00 для более быстрого поиска по списку клиентов - можешь использовать Qlist<quint64>, где в quint64(8 байт) можно запихнуть ip клиента(4 байта) и порт (2байта), оставшиеся 2 байта занулить, например
quint64: |109|064|056|045|064|035|000|000| 0 1 2 3 4 5 6 7 |<--- ip адреса --->|<-- порт -->| сформировать такое число не сложно, а поиск будет быстрее....ну это уже на любителя ;D Название: Re: TCP. отключение от сервера. Отправлено: meandnano от Май 03, 2010, 00:11 не пойму - у меня же сервер слушает один порт, через него все и подключаются. зачем хранить его для каждого клиента отдельно?
Название: Re: TCP. отключение от сервера. Отправлено: garryHotDog от Май 03, 2010, 00:18 а ну да...что то я загнался совсем...это немного из других дебрей, тогда тебе хватит просто quint32
Название: Re: TCP. отключение от сервера. Отправлено: SABROG от Май 03, 2010, 23:45 ну я предполагал, что так и будет, но вся соль то как раз в том, что мне надо socketID получить от уходящего клиента. Его конечно можно задублировать в отдельное поле, но зачем это надо? У тебя должен быть один идентификатор - указатель на класс. Мертвые дескрипторы разве что для отладочных целей, в логи выводить, хотя какую дополнительную информацию может нести номер дескриптора для человека открывшего логи? Можно конечно использовать, чтобы сопоставлять с другими записями, типа вот в 10:00 он подключился, а в 10:02 он отключился, но тут любой порядковый номер сойдет (1, 2, 3, 4). Даже будет информативнее, так как сможешь узнать общее количество активных соединений к тому времени. Ну или просто выводить hex представление адреса в указателе на QTcpSocket. Название: Re: TCP. отключение от сервера. Отправлено: ритт от Май 11, 2010, 14:52 не понимаю зачем вообще нужен SID=Client->socketDescriptor()
у тебя есть адрес сокета - за время жизни сокета его адрес не изменится - вот и используй его в качестве ключа... |