diff options
-rw-r--r-- | client-qt/udm-client-qt/client_session.cpp | 102 | ||||
-rw-r--r-- | client-qt/udm-client-qt/client_session.h | 11 | ||||
-rw-r--r-- | client-qt/udm-client-qt/connect_widget.cpp | 22 | ||||
-rw-r--r-- | client-qt/udm-client-qt/connect_widget.h | 21 | ||||
-rw-r--r-- | client-qt/udm-client-qt/udm-client-qt.pro | 5 | ||||
-rw-r--r-- | server/include/server_session.h | 1 | ||||
-rw-r--r-- | server/src/utilities.cpp | 8 |
7 files changed, 160 insertions, 10 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 \ diff --git a/server/include/server_session.h b/server/include/server_session.h index 23c1fa6..0f7fe62 100644 --- a/server/include/server_session.h +++ b/server/include/server_session.h @@ -43,7 +43,6 @@ class server_session void handle_write_no_read(const boost::system::error_code& error); void handle_command(client_msg *msg); - const int buf_size = 512; char *recv_data_; boost::asio::ip::tcp::socket socket_; }; diff --git a/server/src/utilities.cpp b/server/src/utilities.cpp index 5ea14c1..ab10e30 100644 --- a/server/src/utilities.cpp +++ b/server/src/utilities.cpp @@ -18,6 +18,8 @@ */ +#include <boost/log/trivial.hpp> + #include "utilities.h" #include "../../protocol/udm.pb.h" @@ -33,7 +35,7 @@ std::string replace_home_var(const std::string &path) std::shared_ptr<char*> pack_data(const std::string &buf, int *size_) { -// BOOST_LOG_TRIVIAL(debug)<<__FILE__<<":"<<__LINE__<<"\t"<<__func__; + 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; @@ -48,8 +50,8 @@ std::shared_ptr<char*> pack_data(const std::string &buf, int *size_) std::shared_ptr<char*> pack_msg(server_msg *msg, int *size_) { -// BOOST_LOG_TRIVIAL(debug)<<__FILE__<<":"<<__LINE__<<"\t"<<__func__; -// BOOST_LOG_TRIVIAL(trace)<<"packing message:\n"<<cmd.DebugString(); + 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_); |