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.
How to Remove Document Management Hurdles with X-Docs?
Qt Network Explained (Portuguese)
1. ECOSYSTEM
1 INdT 2012 | Filename.pptx v. 0.1 YYYY-MM-DD Author Document ID [Edit via Insert > Header & Footer]
2. QtNetwork explained
2 INdT 2012 | Filename.pptx v. 0.1 YYYY-MM-DD Author Document ID [Edit via Insert > Header & Footer]
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. TÓPICOS
• High level networking
●
QnetworkAccessManager
●
QnetworkConfiguration
●
QnetworkConfigurationManager
●
QnetworkSession
●
QnetworkRequest
●
QNetworkReply
4 INdT 2012 | Filename.pptx v. 0.1 YYYY-MM-DD Author Document ID [Edit via Insert > Header & Footer]
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. 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. Sockets: QAbstractSocket
• QabstractSocket é uma camada de abstração multi
plataforma para api nativa de network
• Implementa TCP, UDP e sockets locais
• Herda de QIODevice
7 INdT 2012 | Filename.pptx v. 0.1 YYYY-MM-DD Author Document ID [Edit via Insert > Header & Footer]
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.
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
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. QnetworkConfigurationManager
1- Definir o Ponto de Acesso
QNetworkConfigurationManager manager;
//Define que o usuário pode escolher um ponto de acesso
const bool canStartIAP = (manager.capabilities()&
QnetworkConfigurationManager::CanStartAndStopInterfaces);
//Retorna a configuração padrão atual
manager.defaultConfiguration();
16
INdT 2012 | Filename.pptx v. 0.1 YYYY-MM-DD Author Document ID [Edit via Insert > Header & Footer]
17. QnetworkConfiguration
1- Definir o Ponto de Acesso
QNetworkConfigurationManager manager;
//Define que o usuário pode escolher um ponto de acesso
const bool canStartIAP = (manager.capabilities()&
QNetworkConfigurationManager::CanStartAndStopInterfaces);
//Se existe um ponto de acesso padrao. Basta utiliza-lo usando
a configuracao padrao do QNetWorkConfigurarionManager
QNetworkConfiguration cfg = manager.defaultConfiguration();
if (!cfg.isValid() || !canStartIAP) {
// Pontos de acesso nao encontrados ou impossivel se
conectar
// Alertar usuario e fazer tratamento de erro
return;
}
17
INdT 2012 | Filename.pptx v. 0.1 YYYY-MM-DD Author Document ID [Edit via Insert > Header & Footer]
18. QnetworkSession
// Caso a conexao tenha ocorrido com sucesso, abrir um
QNetworkSession usando a configuracao padrao
m_session = new QNetworkSession(cfg);
//Conectar sinais necessarios
connect(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 aconexao
m_session->open();
// Espera a sessão ser aberta e continua a partir dai
m_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. QnetworkAccessManager
1- Criar um Network Access Manager
nam = new QNetworkAccessManager(this);
2- Conectar o sinal finished a um slot para tratar o resultado
QObject::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. QnetworkRequest
1- Criar um Network Access Manager
nam = new QNetworkAccessManager(this);
2- Conectar o sinal finished a um slot para tratar o resultado
QObject::connect(nam, SIGNAL(finished(QNetworkReply*)),
this, SLOT(finishedSlot(QNetworkReply*)));
3- Criar o Request
QUrl 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. QNetworkReply
1- Criar um Network Access Manager
nam = new QNetworkAccessManager(this);
2- Conectar o sinal finished a um slot para tratar o resultado
QObject::connect(nam, SIGNAL(finished(QNetworkReply*)),
this, SLOT(finishedSlot(QNetworkReply*)));
3- Criar o Request
QUrl 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 resposta
QNetworkReply* reply = nam->get(request)
21
INdT 2012 | Filename.pptx v. 0.1 YYYY-MM-DD Author Document ID [Edit via Insert > Header & Footer]
22. QNetworkReply
4- Tratar o Reply
void 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. 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]