summaryrefslogtreecommitdiff
path: root/client-qt
diff options
context:
space:
mode:
Diffstat (limited to 'client-qt')
-rw-r--r--client-qt/udm-client-qt/client_session.cpp102
-rw-r--r--client-qt/udm-client-qt/client_session.h11
-rw-r--r--client-qt/udm-client-qt/connect_widget.cpp22
-rw-r--r--client-qt/udm-client-qt/connect_widget.h21
-rw-r--r--client-qt/udm-client-qt/udm-client-qt.pro5
5 files changed, 155 insertions, 6 deletions
diff --git a/client-qt/udm-client-qt/client_session.cpp b/client-qt/udm-client-qt/client_session.cpp
index 56eb88d..60f462c 100644
--- a/client-qt/udm-client-qt/client_session.cpp
+++ b/client-qt/udm-client-qt/client_session.cpp
@@ -23,6 +23,31 @@
#include <boost/bind.hpp>
#include <boost/log/trivial.hpp>
+std::shared_ptr<char*> pack_data(const std::string &buf, int *size_)
+{
+ BOOST_LOG_TRIVIAL(debug)<<__FILE__<<":"<<__LINE__<<"\t"<<__func__;
+ std::shared_ptr<char*> ptr = std::make_shared<char*>(new char[buf.length() + 4]);
+ int32_t size = buf.length();
+ *size_ = size + 4;
+ (*ptr)[3] = size & 0xff;
+ (*ptr)[2] = (size>>8) & 0xff;
+ (*ptr)[1] = (size>>16) & 0xff;
+ (*ptr)[0] = (size>>24) & 0xff;
+ char *fck = (*ptr)+4;
+ memcpy(fck, buf.data(), buf.length());
+ return ptr;
+}
+
+std::shared_ptr<char*> pack_msg(client_msg *msg, int *size_)
+{
+ BOOST_LOG_TRIVIAL(debug)<<__FILE__<<":"<<__LINE__<<"\t"<<__func__;
+ BOOST_LOG_TRIVIAL(trace)<<"packing message:\n"<<msg->DebugString();
+ std::string msg_buf;
+ msg->SerializeToString(&msg_buf);
+ return pack_data(msg_buf, size_);
+}
+
+
client_session::client_session(QObject *parent, boost::asio::io_service *io_service) : QObject(parent), io_service_(*io_service), socket_(*io_service)
{
@@ -41,21 +66,92 @@ void client_session::client_connect(QString host, int port)
boost::asio::ip::tcp::endpoint ep;
ep.port(port);
ep.address(boost::asio::ip::address::from_string(host.toStdString()));
- socket_.async_connect(ep, boost::bind(&client_session::connect_handler, this, boost::asio::placeholders::error));
+ socket_.async_connect(ep, boost::bind(&client_session::handle_connect, this, boost::asio::placeholders::error));
}
-void client_session::connect_handler(const boost::system::error_code &e)
+void client_session::handle_connect(const boost::system::error_code &e)
{
BOOST_LOG_TRIVIAL(debug)<<__FILE__<<":"<<__LINE__<<"\t"<<typeid(this).name()<<"::"<<__func__;
if(e)
{
//TODO: settings for reconnect count and timeout
+ emit client_connected(false, QString::fromStdString(e.message()));
BOOST_LOG_TRIVIAL(error)<<__FILE__<<":"<<__LINE__<<"\t"<<typeid(this).name()<<"::"<<__func__<<"\terror: "<<e.message();
}
else
{
- //TODO: succesfule connection event
+ emit client_connected(true, QString::fromStdString(e.message()));
+ //listen for messages from server
+ recv_data_ = new char[4];
+ boost::asio::async_read(socket_, boost::asio::buffer(recv_data_, 4), boost::bind(&client_session::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
+ }
+}
+
+void client_session::handle_read(const boost::system::error_code& error, size_t bytes_transferred)
+{
+ if (!error)
+ {
+ std::string s;
+// bool parsed = false;
+ unsigned size = ntohl(*(int32_t*)recv_data_);
+ delete [] recv_data_;
+ char *buf = new char[size];
+ boost::system::error_code ec;
+ socket_.read_some(boost::asio::buffer(buf, size), ec);
+ if(ec)
+ {
+
+ }
+ //TODO: check for error
+ s.append(buf, size);
+ delete [] buf;
+ if(size != s.length())
+ {
+ delete this;
+ return;
+ }
+ //TODO:
+ server_msg msg;
+ if(msg.ParseFromString(s))
+ {
+ //parsed = true;
+ emit server_message_received(msg); //at least one more copy ...., i hope messages will be always small
+ //another way:
+ //make signal work with pointer to server_msg
+ //allocate msg via new server_msg and pass pointer to signal
+ //check if someone connected to signal and delete message if noone
+ //this will be limited to only one client connection because client will need to delete message manually
+ recv_data_ = new char[4];
+ boost::asio::async_read(socket_, boost::asio::buffer(recv_data_, 4), boost::bind(&client_session::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
+ }
+// if(!parsed)
+ else
+ {
+ BOOST_LOG_TRIVIAL(error)<<"failed to parse client message";
+ delete this; //close connection
+ return;
+ }
}
+ else
+ {
+ delete this;
+ }
+}
+
+void client_session::send_message(client_msg &msg)
+{
+ int size = 0;
+ std::shared_ptr<char*> ptr = pack_msg(&msg, &size);
+ boost::asio::async_write(socket_, boost::asio::buffer(*ptr, size), boost::bind(&client_session::handle_write, this, boost::asio::placeholders::error));
+}
+
+void client_session::handle_write(const boost::system::error_code& error)
+{
+ if(error)
+ {
+ //TODO: handle error
+ }
+
}
void client_session::run_io_service()
diff --git a/client-qt/udm-client-qt/client_session.h b/client-qt/udm-client-qt/client_session.h
index f13e96d..192d15b 100644
--- a/client-qt/udm-client-qt/client_session.h
+++ b/client-qt/udm-client-qt/client_session.h
@@ -27,11 +27,14 @@
#include <boost/asio.hpp>
#include <QObject>
+#include "../../protocol/udm.pb.h"
using boost::asio::ip::tcp;
+class server_msg;
+
class client_session : public QObject
{
Q_OBJECT
@@ -42,12 +45,18 @@ public:
tcp::socket& socket();
signals:
+ void client_connected(bool success, QString error_text); //we are in threads, no links here
+ void server_message_received(server_msg msg); //we are in threads, no links here
public slots:
void client_connect(QString host, int port);
void run_io_service();
+ void send_message(client_msg &msg);
+
private:
- void connect_handler(const boost::system::error_code &error);
+ void handle_connect(const boost::system::error_code &error);
+ void handle_read(const boost::system::error_code& error, size_t bytes_transferred);
+ void handle_write(const boost::system::error_code& error);
char *recv_data_;
boost::asio::io_service &io_service_;
tcp::socket socket_;
diff --git a/client-qt/udm-client-qt/connect_widget.cpp b/client-qt/udm-client-qt/connect_widget.cpp
index 8773fb3..ad171cf 100644
--- a/client-qt/udm-client-qt/connect_widget.cpp
+++ b/client-qt/udm-client-qt/connect_widget.cpp
@@ -1,3 +1,25 @@
+/*
+ Copyright © 2015 Gluzskiy Alexandr (sss)
+
+ This file is part of Unknown Download Manager (UDM).
+
+ UDM is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 2 of the License, or
+ (at your option) any later version.
+
+ UDM is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with UDM. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+
+
#include "connect_widget.h"
connect_widget::connect_widget(QWidget *parent) : QWidget(parent)
diff --git a/client-qt/udm-client-qt/connect_widget.h b/client-qt/udm-client-qt/connect_widget.h
index 288eb95..d8c93ad 100644
--- a/client-qt/udm-client-qt/connect_widget.h
+++ b/client-qt/udm-client-qt/connect_widget.h
@@ -1,3 +1,24 @@
+/*
+ Copyright © 2015 Gluzskiy Alexandr (sss)
+
+ This file is part of Unknown Download Manager (UDM).
+
+ UDM is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 2 of the License, or
+ (at your option) any later version.
+
+ UDM is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with UDM. If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+
#ifndef CONNECT_WIDGET_H
#define CONNECT_WIDGET_H
diff --git a/client-qt/udm-client-qt/udm-client-qt.pro b/client-qt/udm-client-qt/udm-client-qt.pro
index ffa95e7..7b6d02d 100644
--- a/client-qt/udm-client-qt/udm-client-qt.pro
+++ b/client-qt/udm-client-qt/udm-client-qt.pro
@@ -33,12 +33,13 @@ greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = udm-client-qt
TEMPLATE = app
-unix:LIBS += -lboost_system -lboost_thread -lboost_log -lpthread
+unix:LIBS += -lboost_thread -lboost_log -lpthread -lprotobuf -lboost_system -ldl
SOURCES += main.cpp\
udm_main.cpp \
client_session.cpp \
- connect_widget.cpp
+ connect_widget.cpp \
+ ../../protocol/udm.pb.cc
HEADERS += udm_main.h \
client_session.h \