Название: UDP ip multicast
Отправлено: crashtua от Май 03, 2011, 22:39
Как у Qt обстоят дела с ip multicast? В стандартном классе вроде бы поддержки ip multicast нету. Там я смотрел извращались с разными библиотеками, типа winsock2.h, вот привожу пример спыжженого кода, который, к сожалению, не работает: C++ (Qt) #ifndef UDPMRECEIVER_H #define UDPMRECEIVER_H #include <QObject> #include <QtNetwork/QUdpSocket> #include <winsock2.h> #include <ws2tcpip.h> class UDPMReceiver : public QObject { Q_OBJECT public: explicit UDPMReceiver(QObject *parent = 0); struct sockaddr_in TivaSinStruct; int TivaSocketId; int TivaPort; ip_mreq TivaMreq; QUdpSocket TivaUdpSocket; signals: public slots: void tiva_readTivaNetPacket(); }; #endif // UDPMRECEIVER_H
C++ (Qt) #include "udpmreceiver.h" #include <stdio.h> #include <QtGui/QMessageBox> UDPMReceiver::UDPMReceiver(QObject *parent) : QObject(parent) { TivaPort=3838; TivaUdpSocket.bind(TivaPort,QUdpSocket::ShareAddress); int TivaSendingFd = TivaUdpSocket.socketDescriptor(); if(TivaSendingFd != -1) { ip_mreq mreq; memset(&mreq,0,sizeof(ip_mreq)); mreq.imr_multiaddr.s_addr = inet_addr("238.38.38.38"); // group addr mreq.imr_interface.s_addr = htons(INADDR_ANY); // use default //Make this a member of the Multicast Group if(setsockopt(TivaSendingFd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char far *)&mreq,sizeof(mreq)) < 0) { printf("TivaNet Memship Error!"); printf("\n"); } // set TTL (Time To Live) unsigned int ttl = 38; // restricted to 38 hops if (setsockopt(TivaSendingFd, IPPROTO_IP, IP_MULTICAST_TTL, (const char *)&ttl, sizeof(ttl) ) < 0) { printf("TimeTo Live Error!"); printf("\n"); } connect(&TivaUdpSocket, SIGNAL(readyRead()), this, SLOT(tiva_readTivaNetPacket())); } } void UDPMReceiver::tiva_readTivaNetPacket() { printf("in tiva_readTivaNetPacket()"); printf("\n"); QString OInMessage; QHostAddress PeerIp; PeerIp.setAddress(PeerIp.Any); quint16 por=TivaPort; while (TivaUdpSocket.hasPendingDatagrams()) { QByteArray datagram; datagram.resize(TivaUdpSocket.pendingDatagramSize( )); TivaUdpSocket.readDatagram(datagram.data(), datagram.size(),&PeerIp,&por); OInMessage=datagram.data(); printf(OInMessage.toStdString().c_str()); printf("\n"); } }
Собственно, tiva_readTivaNetPacket() никогда не вызывается... Кто знает как победить злобный сокет?
Название: Re: UDP ip multicast
Отправлено: LisandreL от Май 04, 2011, 08:51
Как у Qt обстоят дела с ip multicast? В стандартном классе вроде бы поддержки ip multicast нету. Нету инициализации мультикаста, если говорить точнее. Вот пример реализации под Win (для краткости убираю из кода все проверки на успешное выполнение команды): Инклуды: C++ (Qt) #include <ws2tcpip.h> #include <winsock2.h>
Инициализация: C++ (Qt) udpSocket.bind(QHostAddress("0.0.0.0"),4321,QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint); struct ip_mreq mcast; int opt = 1; // 0, если на собственный адрес отправлять не нужно int ttl = 1; int sd = udpSocket.socketDescriptor(); memset(&mcast, 0, sizeof(struct ip_mreq)); mcast.imr_multiaddr.s_addr = inet_addr("225.0.0.0"); mcast.imr_interface.s_addr = inet_addr("0.0.0.0"); setsockopt(sd, IPPROTO_IP, IP_MULTICAST_LOOP, (const char *)&opt, sizeof(int)); setsockopt(sd, IPPROTO_IP, IP_MULTICAST_TTL, (const char *)&ttl, sizeof(ttl)); setsockopt(sd, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mcast.imr_interface.s_addr, sizeof(mcast.imr_interface.s_addr)); setsockopt(sd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mcast, sizeof(mcast)); connect(&udpSocket,SIGNAL(readyRead()),this,SLOT(readUdp()));
Отправка: C++ (Qt) udpSocket.writeDatagram(msg->text().toAscii(),QHostAddress("225.0.0.0"),4321);
Чтение: C++ (Qt) void MainWindow::readUdp() { quint64 size=udpSocket.pendingDatagramSize(); QByteArray buffer; buffer.resize(size); udpSocket.readDatagram(buffer.data(),size); QListWidgetItem* lwi = new QListWidgetItem(buffer); listWidget->addItem(lwi); }
Название: Re: UDP ip multicast
Отправлено: crashtua от Май 04, 2011, 09:37
Спасибо, буду разбираться:) А то после java всякие winapi просто дикость:)
Название: Re: UDP ip multicast
Отправлено: crashtua от Май 04, 2011, 11:24
странно,ваш пример работает отлично только в релизе, а в дебаге не пашет... Может быть дело в либах?
Название: Re: UDP ip multicast
Отправлено: LisandreL от Май 04, 2011, 16:05
У меня работает и там и там. Смотрите что у вас bind, setsockopt, writeDatagram возвращают. Не ругается ли кто-нибудь из них в консоль приложения? Какую версию Qt используете, какой компилятор?
Название: Re: UDP ip multicast
Отправлено: crashtua от Май 04, 2011, 19:20
1 bind 0 setsockopt 0 setsockopt 0 setsockopt 152 writeDatagram В консоль ниче не ругается. Qt 4.7.2, компилятор mingw 3.81(вообщем QT Sdk). На всякий случай приложу настройки проекта: QT += core
QT -= gui
TARGET = UDPReceiver CONFIG += console CONFIG -= app_bundle
TEMPLATE = app LIBS += "C:\QtSDK\mingw\lib\libws2_32.a" LIBS += "C:\QtSDK\Desktop\Qt\4.7.2\mingw\lib\libQtGui4.a" LIBS += "C:\QtSDK\Desktop\Qt\4.7.2\mingw\lib\libQtNetwork4.a" SOURCES += main.cpp \ cmessage.cpp \ udpmulticastsocket.cpp \ io.cpp \ chat.cpp
HEADERS += \ cmessage.h \ udpmulticastsocket.h \ io.h \ chat.h
Название: Re: UDP ip multicast
Отправлено: LisandreL от Май 04, 2011, 21:33
1) Я либы никакие явным образом не подключал (в смысле LIBS += *.а) 2) QT += core network3) QT -= gui LIBS += "C:\QtSDK\Desktop\Qt\4.7.2\mingw\lib\libQtGui4.a" ORLY? :o
Название: Re: UDP ip multicast
Отправлено: crashtua от Май 05, 2011, 15:54
без LIBS += "C:\QtSDK\mingw\lib\libws2_32.a" ругается на отсуствие ссылок...
Название: Re: UDP ip multicast
Отправлено: LisandreL от Май 06, 2011, 22:44
без LIBS += "C:\QtSDK\mingw\lib\libws2_32.a" ругается на отсуствие ссылок...
Да, наврал. LIBS += libwsock32
Название: Re: UDP ip multicast
Отправлено: crashtua от Май 08, 2011, 16:27
создал новый проект, и в дебаге и в релизе нормально работает.... Мистика...
|