Your SlideShare is downloading. ×
0
ECOSYSTEM1   INdT 2012 | Filename.pptx v. 0.1 YYYY-MM-DD Author Document ID [Edit via Insert > Header & Footer]
QtNetwork explained2   INdT 2012 | Filename.pptx v. 0.1 YYYY-MM-DD Author Document ID [Edit via Insert > Header & Footer]
TÓPICOS    • Introdução ao QtNetwork    • Por que usar QtNetwork    • Sockets       ●         QAbstractSocket           ● ...
TÓPICOS    • High level networking       ●         QnetworkAccessManager            ●                   QnetworkConfigurat...
Introdução ao QtNetwork • QtNetwork é um módulo do Qt • Provê uma interface cross platforma para escrever aplicações   cli...
Por que usar QtNetwork?int main(){                                                                  int main()  int fd = s...
Sockets: QAbstractSocket    • QabstractSocket é uma camada de abstração multi      plataforma para api nativa de network  ...
Sockets: QTcpSocket ●     Subclasse de conveniência do QAbstractSocket ●     Pode ser utilizado pra implementar vários tip...
Sockets: QTcpSocket                                                                  ClientSocket::ClientSocket(QObject *p...
Sockets: QTcpServer ●     Precisa receber conexões? Essa é a classe certa. ●     Pode ser single threaded or multi threade...
Sockets: QTcpServerServer::Server(QObject *parent)  : QtcpServer(parent)  , m_serverInfo(){}void Server::start(){  listen(...
Sockets: QudpSocket BroadcastBroadcastAnnounce::BroadcastAnnounce(QObject *parent)    : QObject(parent)    , m_socket(new ...
Sockets: QudpSocket BroadcastBroadcastAnnounce::BroadcastAnnounce(QObject *parent)                                 Broadca...
Sockets: QudpSocket MulticastMulticastAnnounce::MulticastAnnounce(QObject *parent)                                        ...
Sockets: QUdpSocket ●     Subclasse de conveniência do QabstractSocket para     UDP ●     Envio de pacotes de dados ao inv...
QnetworkConfigurationManager1- Definir o Ponto de AcessoQNetworkConfigurationManager manager;//Define que o usuário pode e...
QnetworkConfiguration1- Definir o Ponto de AcessoQNetworkConfigurationManager manager;//Define que o usuário pode escolher...
QnetworkSession// Caso a conexao tenha ocorrido com sucesso, abrir umQNetworkSession usando a configuracao padraom_session...
QnetworkAccessManager1- Criar um Network Access Managernam = new QNetworkAccessManager(this);2- Conectar o sinal finished ...
QnetworkRequest1- Criar um Network Access Managernam = new QNetworkAccessManager(this);2- Conectar o sinal finished a um s...
QNetworkReply1- Criar um Network Access Managernam = new QNetworkAccessManager(this);2- Conectar o sinal finished a um slo...
QNetworkReply4- Tratar o Replyvoid MyHttpEngine::finishedSlot(QNetworkReply* reply) {        // Ler Atributos do Repply co...
Canais de comunicação• @nokiadev_brasil• rodrigo.belem@openbossa.org 23   INdT 2012 | Filename.pptx v. 0.1 YYYY-MM-DD Auth...
Upcoming SlideShare
Loading in...5
×

Qt Network Explained (Portuguese)

473

Published on

Desenvolver uma aplicação que precisa de comunicar com a rede não precisa ser complicado. Neste webinar será mostrado como o Qt torna programação para rede muito mais simples. Será dado um rápido overview de como criar sockets UDP e TCP, broadcast e multicast além de fazer requisições REST usando somente a API do QtNetwork.

Published in: Technology, Education
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
473
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
7
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Transcript of "Qt Network Explained (Portuguese)"

  1. 1. ECOSYSTEM1 INdT 2012 | Filename.pptx v. 0.1 YYYY-MM-DD Author Document ID [Edit via Insert > Header & Footer]
  2. 2. QtNetwork explained2 INdT 2012 | Filename.pptx v. 0.1 YYYY-MM-DD Author Document ID [Edit via Insert > Header & Footer]
  3. 3. TÓPICOS • Introdução ao QtNetwork • Por que usar QtNetwork • Sockets ● QAbstractSocket ● QTcpSocket – QsslSocket ● QTcpServer ● QudpSocket – Broadcast – Multicast (somente 4.8 !symbian)3 INdT 2012 | Filename.pptx v. 0.1 YYYY-MM-DD Author Document ID [Edit via Insert > Header & Footer]
  4. 4. TÓPICOS • High level networking ● QnetworkAccessManager ● QnetworkConfiguration ● QnetworkConfigurationManager ● QnetworkSession ● QnetworkRequest ● QNetworkReply4 INdT 2012 | Filename.pptx v. 0.1 YYYY-MM-DD Author Document ID [Edit via Insert > Header & Footer]
  5. 5. Introdução ao QtNetwork • QtNetwork é um módulo do Qt • Provê uma interface cross platforma para escrever aplicações cliente servidor TCP/IP • Suporta proxy • Possui classes para realizar requests http e ftp, acessar web services e tratar suas respostas. • Pegar informações sobre dispositivos de rede • É possível ainda gerenciar o estado de conexão com a rede, ter configurações específicas para cada uma e realizar ações.
  6. 6. Por que usar QtNetwork?int main(){ int main() int fd = socket(AF_INET, SOCK_STREAM, 0); { if (fd == 1) { QCoreApplication app(argc, argv); printf("can not create socket"); exit(1); } QTcpServer server; struct sockaddr_in saddr; bzero(&saddr, sizeof(saddr)); server.listen(QHostAddress::Any, 1100); saddr.sin_family = AF_INET; saddr.sin_port = htons(1100); saddr.sin_addr.s_addr = htonl(INADDR_ANY); while (server.waitForNewConnection()) { do { if (bind(fd,(struct sockaddr *)&saddr, sizeof(saddr)) == 1) { QTcpSocket *socket = server.nextPendingConnection(); printf("error bind failed"); socket->write(“Hello, world!”); exit(1); } socket->disconnectFromHost(); if (listen(fd, 10) == 1) socket->waitForDisconnected(); { delete socket; printf("error listen failed"); exit(1); } while (server.hasPendingConnections()); } } for(;;) { int connfd = accept(fd, NULL, NULL); } if(connfd <= 0) { printf("error accept failed"); exit(1); } write(connfd, "Hello world!n", 13); close(connfd); } return 0;}
  7. 7. Sockets: QAbstractSocket • QabstractSocket é uma camada de abstração multi plataforma para api nativa de network • Implementa TCP, UDP e sockets locais • Herda de QIODevice7 INdT 2012 | Filename.pptx v. 0.1 YYYY-MM-DD Author Document ID [Edit via Insert > Header & Footer]
  8. 8. Sockets: QTcpSocket ● Subclasse de conveniência do QAbstractSocket ● Pode ser utilizado pra implementar vários tipos protocolos ● Stream de dados contínuo ● Poder ser usado de maneira asíncrona ou síncrona.
  9. 9. Sockets: QTcpSocket ClientSocket::ClientSocket(QObject *parent)ServerSocket::ServerSocket(QObject *parent) : QTcpSocket(parent) : QTcpSocket(parent) {{ connect(this, SIGNAL(readyRead()), connect(this, SIGNAL(readyRead()), this, SLOT(onReadyRead())); this, SLOT(onReadyRead()));} connect(this, SIGNAL(disconnected()),void ServerSocket::onServerInfoResponse(const QVariantMap &map) this, SLOT(onDisconnected()));{ QJson::Serializer serializer; connect(this, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(onError(QAbstractSocket::SocketError))); write(serializer.serialize(map)); } flush();} void ClientSocket::onDisconnected() {void ServerSocket::onServerStatusChanged(const QString &status) qDebug() << "[ClientSocket] Client disconnected!"; }{ QVariantMap map; void ClientSocket::onError(QAbstractSocket::SocketError error) map["what"] = "server"; { map["action"] = "statusChanged"; map["status"] = status; qDebug() << "[ClientSocket] Error: " << error; } QJson::Serializer serializer; write(serializer.serialize(map)); void ClientSocket::requestServerInfo() flush(); {} QVariantMap map; QJson::Serializer serializer;void ServerSocket::onReadyRead(){ while (canReadLine()) { map["what"] = "server"; QByteArray line = readLine(); map["action"] = "serverInfo"; write(serializer.serialize(map)"); bool parserOk = true; } QJson::Parser parser; void ClientSocket::onQJsonParsingFinished(const QVariant &json, bool ok, const QString &error_msg) QVariant var = parser.parse(line, &parserOk); { if (!parserOk) { if (!ok) { qWarning() qWarning() << Q_FUNC_INFO << "json error at" << error_msg; << Q_FUNC_INFO return; << "json error at" } << parser.errorLine() << parser.errorString(); QVariantMap map = json.toMap(); } else { QString what = map["what"].toString(); QVariantMap map = var.toMap(); if (what == "server") { QString what = map["what"].toString(); if (what == "server") { QString action = map["action"].toString(); QString action = map["action"].toString(); if (action == "serverInfo") { if (action == "info") { emit serverInfoReceived(map); emit serverInfoRequested(); } } } } } } }}
  10. 10. Sockets: QTcpServer ● Precisa receber conexões? Essa é a classe certa. ● Pode ser single threaded or multi threaded ● Single threaded ● Um ou vários sockets usando mesmo Event loop ● Ou Bloqueante ● Multi threaded ● Um socket por thread – Bloqueante – Ou um Event loop por thread
  11. 11. Sockets: QTcpServerServer::Server(QObject *parent) : QtcpServer(parent) , m_serverInfo(){}void Server::start(){ listen(QHostAddress::Any, 12345);}void Server::incomingConnection(int socketDescriptor){ ServerSocket *sock = new ServerSocket; sock->setSocketDescriptor(socketDescriptor); QThread *thread = new QThread; sock->moveToThread(thread); connect(sock, SIGNAL(disconnected()), sock, SLOT(deleteLater())); connect(sock, SIGNAL(destroyed()), thread, SLOT(quit())); connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); connect(this, SIGNAL(statusChanged(const Qstring &)), sock, SLOT(onServerStatusChanged(const Qstring &))); connect(sock, SIGNAL(serverInfoRequested()), this, SLOT(onServerInfoRequested())); thread->start();}void Server::onServerInfoRequested(){ ServerSocket *sock = qobject_cast<ServerSocket*>(sender()); if (!sock) return; QMetaObject::invokeMethod(sock, "onServerInfoResponse", Q_ARG(QVariantMap, m_serverInfo));}
  12. 12. Sockets: QudpSocket BroadcastBroadcastAnnounce::BroadcastAnnounce(QObject *parent) : QObject(parent) , m_socket(new QUdpSocket(this)) , m_timer(new QTimer(this)) , m_serverInfo(){ connect(m_timer, SIGNAL(timeout()), this, SLOT(sendDatagram()));}void BroadcastAnnounce::start(){ if (m_timer->isActive()) m_timer->stop(); m_timer->start(1000);}void BroadcastAnnounce::stop(){ m_timer->stop();}void BroadcastAnnounce::setServerInfo(const QVariantMap &map){ m_serverInfo = map;}void BroadcastAnnounce::sendDatagram(){ QByteArray datagram; QDataStream out(&datagram, QIODevice::WriteOnly); out.setVersion(QDataStream::Qt_4_7); out << QVariant(m_serverInfo); m_socket->writeDatagram(datagram.data(), datagram.size(), QHostAddress::Broadcast,UDP_PORT);}
  13. 13. Sockets: QudpSocket BroadcastBroadcastAnnounce::BroadcastAnnounce(QObject *parent) BroadcastDiscover::BroadcastDiscover(QObject *parent) : QObject(parent) : QObject(parent) , m_socket() , m_timer(new QTimer(this)) , m_socket(new QUdpSocket(this)) { , m_timer(new QTimer(this)) connect(m_timer, SIGNAL(timeout()), this, SLOT(stop())); } , m_serverInfo(){ void BroadcastDiscover::start() { connect(m_timer, SIGNAL(timeout()), this, SLOT(sendDatagram())); m_socket = new QUdpSocket(this);} m_socket->bind(UDP_PORT, QUdpSocket::ShareAddress); connect(m_socket, SIGNAL(readyRead()), this, SLOT(processDatagrams()));void BroadcastAnnounce::start() m_timer->start(10000); }{ if (m_timer->isActive()) void BroadcastDiscover::stop() { m_timer->stop(); disconnect(m_socket, SIGNAL(readyRead()), this, SLOT(processDatagrams())); m_socket->close(); m_timer->start(1000); emit timeout();} } void BroadcastDiscover::processDatagrams()void BroadcastAnnounce::stop() { QUdpSocket *socket = qobject_cast<QUdpSocket *>(sender());{ if (!socket) m_timer->stop(); return;} while (socket->hasPendingDatagrams()) { QByteArray datagram;void BroadcastAnnounce::setServerInfo(const QVariantMap &map) QHostAddress host;{ datagram.resize(socket->pendingDatagramSize()); m_serverInfo = map; socket->readDatagram(datagram.data(), datagram.size(), &host);} QVariant message;void BroadcastAnnounce::sendDatagram() QDataStream dataStream(&datagram, QIODevice::ReadOnly);{ dataStream >> message; QByteArray datagram; const QVariantMap map = message.toMap(); QDataStream out(&datagram, QIODevice::WriteOnly); if (map["app_id"].toString() == APP_ID) { const QString action = map["action"].toString(); out.setVersion(QDataStream::Qt_4_7); if (action == "serverAnnounce") { out << QVariant(m_serverInfo); emit serverFound(map); } m_socket->writeDatagram(datagram.data(), datagram.size(), QHostAddress::Broadcast, }UDP_PORT); }} }
  14. 14. Sockets: QudpSocket MulticastMulticastAnnounce::MulticastAnnounce(QObject *parent) MulticastDiscover::MulticastDiscover(QObject *parent) : QObject(parent) : QObject(parent) , m_socket() , m_socket(new QUdpSocket(this)) , m_timer(new QTimer(this)) { , m_timer(new QTimer(this)) connect(m_timer, SIGNAL(timeout()), this, SLOT(stop())); , m_serverInfo() }{ void MulticastDiscover::start() connect(m_timer, SIGNAL(timeout()), this, SLOT(sendDatagram())); { m_socket = new QUdpSocket(this); m_socket->setSocketOption(QAbstractSocket::MulticastTtlOption, 1); m_socket->bind(UDP_PORT, QUdpSocket::ShareAddress); m_socket->joinMulticastGroup(QHostAddress("239.255.43.21"));} connect(m_socket, SIGNAL(readyRead()), this, SLOT(processDatagrams()));void MulticastAnnounce::start() m_timer->start(10000);{ } if (m_timer->isActive()) void MulticastDiscover::stop() m_timer->stop(); { disconnect(m_socket, SIGNAL(readyRead()), this, SLOT(processDatagrams())); m_timer->start(1000); m_socket->close();} emit timeout(); }void MulticastAnnounce::stop() void MulticastDiscover::processDatagrams(){ { m_timer->stop(); QUdpSocket *socket = qobject_cast<QUdpSocket *>(sender()); if (!socket)} return; while (socket->hasPendingDatagrams()) {void MulticastAnnounce::setServerInfo(const QVariantMap &map) QByteArray datagram;{ QHostAddress host; m_serverInfo = map; datagram.resize(socket->pendingDatagramSize());} socket->readDatagram(datagram.data(), datagram.size(), &host);void MulticastAnnounce::sendDatagram() QVariant message; QDataStream dataStream(&datagram, QIODevice::ReadOnly); dataStream >> message;{ QByteArray datagram; const QVariantMap map = message.toMap(); if (map["app_id"].toString() == APP_ID) { QDataStream out(&datagram, QIODevice::WriteOnly); const QString action = map["action"].toString(); out.setVersion(QDataStream::Qt_4_8); if (action == "serverAnnounce") { out << QVariant(m_serverInfo); emit serverFound(map); } } m_socket->writeDatagram(datagram.data(), datagram.size(), QHostAddress("239.255.43.21"), UDP_PORT); } }}
  15. 15. Sockets: QUdpSocket ● Subclasse de conveniência do QabstractSocket para UDP ● Envio de pacotes de dados ao invés de stream contínuo ● Possui suporte a Broadcast ● Desde o Qt 4.8 suporte a Multicast
  16. 16. QnetworkConfigurationManager1- Definir o Ponto de AcessoQNetworkConfigurationManager manager;//Define que o usuário pode escolher um ponto de acessoconst bool canStartIAP = (manager.capabilities()&QnetworkConfigurationManager::CanStartAndStopInterfaces);//Retorna a configuração padrão atualmanager.defaultConfiguration(); 16 INdT 2012 | Filename.pptx v. 0.1 YYYY-MM-DD Author Document ID [Edit via Insert > Header & Footer]
  17. 17. QnetworkConfiguration1- Definir o Ponto de AcessoQNetworkConfigurationManager manager;//Define que o usuário pode escolher um ponto de acessoconst bool canStartIAP = (manager.capabilities()&QNetworkConfigurationManager::CanStartAndStopInterfaces);//Se existe um ponto de acesso padrao. Basta utiliza-lo usandoa configuracao padrao do QNetWorkConfigurarionManagerQNetworkConfiguration cfg = manager.defaultConfiguration();if (!cfg.isValid() || !canStartIAP) {// Pontos de acesso nao encontrados ou impossivel seconectar// Alertar usuario e fazer tratamento de erroreturn;} 17 INdT 2012 | Filename.pptx v. 0.1 YYYY-MM-DD Author Document ID [Edit via Insert > Header & Footer]
  18. 18. QnetworkSession// Caso a conexao tenha ocorrido com sucesso, abrir umQNetworkSession usando a configuracao padraom_session = new QNetworkSession(cfg);//Conectar sinais necessariosconnect(m_session, SIGNAL(closed()), this, SLOT(closed()));connect(m_session,SIGNAL(stateChanged(QNetworkSession::State)), this,SLOT(stateChanged(QNetworkSession::State)));connect(m_session,SIGNAL(error(QNetworkSession::SessionError)), this,SLOT(error(QNetworkSession::SessionError)));Abrir aconexaom_session->open();// Espera a sessão ser aberta e continua a partir daim_session->waitForOpened();Para fechar a sessão, usar o slot finished() 18 INdT 2012 | Filename.pptx v. 0.1 YYYY-MM-DD Author Document ID [Edit via Insert > Header & Footer]
  19. 19. QnetworkAccessManager1- Criar um Network Access Managernam = new QNetworkAccessManager(this);2- Conectar o sinal finished a um slot para tratar o resultadoQObject::connect(nam, SIGNAL(finished(QNetworkReply*)), this, SLOT(finishedSlot(QNetworkReply*))); 19 INdT 2012 | Filename.pptx v. 0.1 YYYY-MM-DD Author Document ID [Edit via Insert > Header & Footer]
  20. 20. QnetworkRequest1- Criar um Network Access Managernam = new QNetworkAccessManager(this);2- Conectar o sinal finished a um slot para tratar o resultadoQObject::connect(nam, SIGNAL(finished(QNetworkReply*)), this, SLOT(finishedSlot(QNetworkReply*)));3- Criar o RequestQUrl url(http://query.yahooapis.com/v1/public/yql);url.addQueryItem(QUERY_PARAM,QLatin1String("select+*+from+geo.placefinder+where+text="")+ "Sao Paulo" + QLatin1String("""));url.addQueryItem("format", "json");QnetworkRequest request(url); 20 INdT 2012 | Filename.pptx v. 0.1 YYYY-MM-DD Author Document ID [Edit via Insert > Header & Footer]
  21. 21. QNetworkReply1- Criar um Network Access Managernam = new QNetworkAccessManager(this);2- Conectar o sinal finished a um slot para tratar o resultadoQObject::connect(nam, SIGNAL(finished(QNetworkReply*)), this, SLOT(finishedSlot(QNetworkReply*)));3- Criar o RequestQUrl url(http://query.yahooapis.com/v1/public/yql);url.addQueryItem(QUERY_PARAM,QLatin1String("select+*+from+geo.placefinder+where+text="")+ "Sao Paulo" + QLatin1String("""));url.addQueryItem("format", "json");QnetworkRequest request(url);4- Guardar o reply do request par ser usado como identificador da respostaQNetworkReply* reply = nam->get(request) 21 INdT 2012 | Filename.pptx v. 0.1 YYYY-MM-DD Author Document ID [Edit via Insert > Header & Footer]
  22. 22. QNetworkReply4- Tratar o Replyvoid MyHttpEngine::finishedSlot(QNetworkReply* reply) { // Ler Atributos do Repply como ocodigo de Status HTTP QVariant statusCodeV = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);void MyHttpEngine::finishedSlot(QNetworkReply* reply) { // Ler Atributos do Repply como o codigo de Status HTTP QVariant statusCodeV = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute); // Ou a URL, se esta tiver sido redirecionada: QVariant redirectionTargetUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute); // Verificar se houve erro if (reply->error() == QnetworkReply::NoError) { // Se nao houve erro, ler os dados da resposta //Ex1: Criando um QImage da resposta QImageReader imageReader(reply); QImage pic = imageReader.read(); }} 22 INdT 2012 | Filename.pptx v. 0.1 YYYY-MM-DD Author Document ID [Edit via Insert > Header & Footer]
  23. 23. Canais de comunicação• @nokiadev_brasil• rodrigo.belem@openbossa.org 23 INdT 2012 | Filename.pptx v. 0.1 YYYY-MM-DD Author Document ID [Edit via Insert > Header & Footer]
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×