Название: Чат клиент-сервер на блокирующих UDP сокетах. Отправлено: Silver_swift от Февраль 24, 2011, 09:40 Всем привет!
Мне нужно сделать чат с клиентской и серверной частями с использованием блокирующих UDP сокетов. Это задание на лабораторной инсте поэтому нужно сделать именно так. Проблема в том, что я в Qt новичок (где-то второй месяц читаю книгу Макса Шлее), знания С++ у меня есть и в принципе из того, что я читаю мне все более-менее понятно. Я просто физически не успею освоить всю книгу к сроку сдачи лабораторных. Потому прошу помощи. Мне нужны Ваши советы по следующим вопросам: 1. Какой виджет лучше использовать для отображеня принятых сообщений, а какой для списка пользователей? 2. Как вообще реализовать передачу сообщения? То есть я худо-бедно представляю как сделать интерфейс и могу создать объект QUdpSocket и что-то в него писать/читать. Но я не очень представляю как лучше "подружить" интерфейс и сокет при том, что сокет и интерфейс должны создаваться в разных потоках (чтобы при использовании сокета интерфейс не подвисал или есть другие способы избежать подвисания?). И я не знаю как сделать сокет блокирующим. Вроде пока больше трудностей не возникло, но по мере выполнения работы буду что-то добавлять. P.S. Поймите правильно только, мне не надо готовых кодов. Мне нужно чтобы вы помогли разобраться с тем, что мне не понятно и подсказали какие классы и методы лучше использовать для моих нужд ибо я просто не успеваю во всем разобраться. А как что реализовывать я посмотрю в справке, если чего не пойму снова к вам обращусь :) Очень надеюсь на понимание и поддержку сообщества. Не дайте программисту во мне умереть :) Название: Re: Чат клиент-сервер на блокирующих UDP сокетах. Отправлено: Ubuntu_linux от Февраль 24, 2011, 11:31 Для сообщений используй QPlainTextEdit.
Для списка юзеров используй QListWidget. Пример клиент-сервер посмотри в асистенте, там проще некуда... или полязь на форуме, тут много примеров. А что имеется под блокировкой ? Название: Re: Чат клиент-сервер на блокирующих UDP сокетах. Отправлено: Silver_swift от Февраль 24, 2011, 12:44 Если создать блокирующий сокет в С, то когда выполняется чтение или запись все другие операции будут блочиться, пока не закончится чтение/запись. Поэтому если использовать sys/socket.h или winsock.h, надо создавать сокет в отдельном потоке.
А в Qt будто бы по умолчанию создается не блокирующий сокет. Что-то вроде того... Может надо какой-то другой конструктор использовать для блокирующего сокета или еще чего? В примере чат сделан все в одной проге мне пока тяжко разбираться в коде. Буду мучить дальше. Название: Re: Чат клиент-сервер на блокирующих UDP сокетах. Отправлено: Igore от Февраль 24, 2011, 18:50 Если будешь использовать waitForConnected, waitForBytesWritten, waitForReadyRead то это будет блокирущее обращение к сокету, если программу организовать на signal -> slot, то будут не блокирующие signal -ы (connected, error, readyRead) и т.д.
Название: Re: Чат клиент-сервер на блокирующих UDP сокетах. Отправлено: Ubuntu_linux от Февраль 24, 2011, 19:02 Так используй метод
bool QObject::blockSignals ( bool block ) чтоб заблокировать сигнал от(к) сокета. или чтоб дождатся завершения какого-то процеса. QEventLoop loop; connect(SameProcess,SIGNAL(SameSignal),&loop,SLOT(quit())); loop.exec(); Название: Re: Чат клиент-сервер на блокирующих UDP сокетах. Отправлено: Silver_swift от Февраль 24, 2011, 23:49 Спасибо за участие!
Возник вопрос. Пока чат был одной программой все было более менее нормально и он даже отсылал сам себе сообщения. Но стоило разделить программу на клиента и сервера как возник затык. Подозреваю что затык в 3 строчке: Код: Socket=new QUdpSocket (this); На С в sys/socket.h сервер присваивал сокету адрес, а клиент подключался к нему вызовом connect(). Только в Qt connect это совсем не то. Встает вопрос: как быть? ??? Название: Re: Чат клиент-сервер на блокирующих UDP сокетах. Отправлено: Silver_swift от Февраль 25, 2011, 09:16 Глупость вчера написал. Не должно быть в udp никакого вызова connect(). В udp соединение не устанавливается. Просто убрал bind из клиентской части. Использую readDatagram и writeDatagram. Сообщения отправляются клиентом, читаются на сервере и отправляются клиенту, но до клиента не доходят.
В чем может быть причина? Название: Re: Чат клиент-сервер на блокирующих UDP сокетах. Отправлено: kuzulis от Февраль 25, 2011, 10:02 Цитировать В чем может быть причина? В том, что UDP не гарантирует доставку, или у вас где-то ошибка. Название: Re: Чат клиент-сервер на блокирующих UDP сокетах. Отправлено: Silver_swift от Февраль 26, 2011, 21:29 Пакеты не теряются. Я ж через loopback пока проверяю.
Ошибка наверняка где-то есть и заключается в неправильном использовании QUdpSocket. Создаю объект QUdpSocket, присваиваю ему адрес и порт. Могу в этот сокет писать, могу из него читать по сигналу readyRead(). В клиентской программе присвоить тот же порт сокету я не могу иначе при запуске двух программ будет конфликт. Но (!) без выполнения bind() из сокета ничего не читается. Из этого два вывода: - либо для сокетов без присвоенных имен нельзя использовать readyRead() - либо для таких сокетов нельзя использовать readDatagram() На этот вопрос я самостоятельно ответа не нашел. Посему прошу ответить вас, если можно. Тупо сделал сокеты для клиента и сервера на разных портах. Работать работает, но это корявый способ. Кто-нибудь может растолковать как в Qt сделать так чтоб можно было использовать сокет на чтение и запись с двух концов? edited: Делаю что-то вроде этого: Код: ClientSocket=new QUdpSocket (this); Код: void client::readUDP() |