summaryrefslogtreecommitdiffstats
path: root/src/net/pvsClientConnection.cpp
diff options
context:
space:
mode:
authorSebastian2010-05-12 19:42:27 +0200
committerSebastian2010-05-12 19:42:27 +0200
commitce3329047d378a14006ce74ec273ac59e3375303 (patch)
tree782430f270b4c7aca1b35d5b7813518e3797c555 /src/net/pvsClientConnection.cpp
downloadpvs-ce3329047d378a14006ce74ec273ac59e3375303.tar.gz
pvs-ce3329047d378a14006ce74ec273ac59e3375303.tar.xz
pvs-ce3329047d378a14006ce74ec273ac59e3375303.zip
initial import of latest svn version
Diffstat (limited to 'src/net/pvsClientConnection.cpp')
-rw-r--r--src/net/pvsClientConnection.cpp178
1 files changed, 178 insertions, 0 deletions
diff --git a/src/net/pvsClientConnection.cpp b/src/net/pvsClientConnection.cpp
new file mode 100644
index 0000000..dff40d5
--- /dev/null
+++ b/src/net/pvsClientConnection.cpp
@@ -0,0 +1,178 @@
+/*
+# Copyright (c) 2009,2010 - OpenSLX Project, Computer Center University of
+# Freiburg
+#
+# This program is free software distributed under the GPL version 2.
+# See http://openslx.org/COPYING
+#
+# If you have any feedback please consult http://openslx.org/feedback and
+# send your suggestions, praise, or complaints to feedback@openslx.org
+#
+# General information about OpenSLX can be found at http://openslx.org/
+# -----------------------------------------------------------------------------
+# pvsClientConnection.cpp
+# - ???.
+# -----------------------------------------------------------------------------
+*/
+
+#include "pvsClientConnection.h"
+#include "pvsListenServer.h"
+#include "src/util/consoleLogger.h"
+
+#include <cassert>
+#include <QtNetwork/QHostAddress>
+
+
+PVSClientConnection::PVSClientConnection(PVSListenServer* server, QSslSocket* sock)
+{
+ assert(sock);
+ assert(server);
+ _socket = sock;
+ _incomplete = NULL;
+ _toldDisconnect = false;
+ _server = server;
+ _lastData = time(NULL);
+ sock->setParent(this); // for automatic deletion
+ connect(_socket, SIGNAL(readyRead()), this, SLOT(sock_dataArrival()));
+ connect(_socket, SIGNAL(disconnected()), this, SLOT(sock_closed()));
+ connect(_socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(sock_error(QAbstractSocket::SocketError)));
+}
+
+PVSClientConnection::~PVSClientConnection()
+{
+ this->closeConnection();
+ if (_incomplete != NULL) delete _incomplete;
+ if (_socket != NULL)
+ {
+ disconnect(_socket, SIGNAL(readyRead()), this, SLOT(sock_dataArrival()));
+ disconnect(_socket, SIGNAL(disconnected()), this, SLOT(sock_closed()));
+ disconnect(_socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(sock_error(QAbstractSocket::SocketError)));
+ _socket->abort();
+ }
+}
+
+void PVSClientConnection::closeConnection()
+{
+ if (_toldDisconnect) return; // we already got served
+ if (_socket == NULL || _socket->state() == QAbstractSocket::UnconnectedState)
+ {
+ // should not happen but handled anyway
+ _toldDisconnect = true;
+ _server->disconnectClient(this);
+ return;
+ }
+ if (_socket->state() == QAbstractSocket::ClosingState) return; // sock_close() slot should eventually be called, nothing to do
+ if (_socket->state() == QAbstractSocket::ConnectedState) // this is what should be the case normally
+ {
+ _socket->disconnectFromHost(); // graceful shutdown of socket, sock_close() will be called once complete
+ return;
+ }
+ // otherwise the socket is in some unknown state, so do a harsh shutdown
+ _socket->abort();
+ _toldDisconnect = true;
+ _server->disconnectClient(this);
+}
+
+void PVSClientConnection::sock_dataArrival()
+{
+ if (_socket == NULL || _socket->state() != QAbstractSocket::ConnectedState)
+ {
+ ConsoleLog writeError("dataArrival called in bad state");
+ return;
+ }
+
+ _lastData = time(NULL);
+ while (_socket->bytesAvailable())
+ {
+ int retval = 0;
+ do
+ {
+ if (_incomplete == NULL) _incomplete = new PVSMsg(); // we need a pvsmsg object
+ retval = _incomplete->readMessage(_socket); // let the message read data from socket
+ if (retval == -1) // error parsing msg, disconnect client!
+ {
+ this->closeConnection();
+ return;
+ }
+ if (retval == 1) // message is complete
+ {
+ _server->handleClientMsg(_id, *_incomplete);
+ delete _incomplete; // ...and delete...
+ _incomplete = NULL; // ...so the next msg can be parsed
+ }
+ } while (retval == 1);
+ }
+}
+
+void PVSClientConnection::sock_closed()
+{
+ // should this be unreliable in some way i suggest using the signal "stateChanged()" instead
+ // and check if the state changed to unconnected.
+ if (_toldDisconnect) return;
+ _toldDisconnect = true;
+ _server->disconnectClient(this);
+}
+
+void PVSClientConnection::sock_error(QAbstractSocket::SocketError errcode)
+{
+ this->closeConnection();
+}
+
+/*
+void PVSClientConnection::push_back_receive(PVSMsg newMsg)
+{
+ _recQueue.push_back(newMsg);
+}
+*/
+
+bool PVSClientConnection::push_back_send(PVSMsg newMsg)
+{
+ if (_socket == NULL || _socket->state() != QAbstractSocket::ConnectedState) return false;
+ newMsg.setSndID(_id);
+ int len;
+ char data[2000];
+ char *tmp = data;
+ if (!newMsg.getBinaryData(tmp, len))
+ {
+ printf("Message empty. Ignored.\n");
+ return false;
+ }
+ QByteArray ba;
+ ba.append(tmp, len);
+ int ret = (int)_socket->write(ba);
+ //printf("Sent %d of %d bytes.\n", ret, len);
+ if (ret == -1)
+ {
+ this->closeConnection();
+ return false;
+ }
+ return true;
+}
+
+QSslSocket* PVSClientConnection::getSocket()
+{
+ return _socket;
+}
+
+void PVSClientConnection::setID(unsigned int id)
+{
+ _id = id;
+ this->push_back_send(PVSMsg(PVSLOGIN, "ID", int2String(_id)));
+}
+
+void PVSClientConnection::ping()
+{
+ // still needs flag/timer to check for a ping timeout (and a reply from the client)
+ this->push_back_send(PVSMsg(PVSCOMMAND, "PING", "HELLO?", _id));
+}
+
+QString PVSClientConnection::getAddress()
+{
+ if (_socket == NULL) return QString();
+ return _socket->peerAddress().toString();
+}
+
+QString PVSClientConnection::getNameUser()
+{
+ return getUserName();
+}