summaryrefslogtreecommitdiffstats
path: root/src/net
diff options
context:
space:
mode:
authorSebastien Braun2010-07-15 01:12:17 +0200
committerSebastien Braun2010-07-15 01:12:17 +0200
commit94b88e75b9ebeaf9abb2adef130fdf971884e7b4 (patch)
treecc0bb545880b0d159267290d7aa5c63693905dcb /src/net
parentChange to shorter NAK intervals for performance. (diff)
downloadpvs-94b88e75b9ebeaf9abb2adef130fdf971884e7b4.tar.gz
pvs-94b88e75b9ebeaf9abb2adef130fdf971884e7b4.tar.xz
pvs-94b88e75b9ebeaf9abb2adef130fdf971884e7b4.zip
* Upgrade OpenPGM to current trunk
* Implement wait-for-shutdown for McastPGMSocket * Work around bug in UDP encapsulation
Diffstat (limited to 'src/net')
-rw-r--r--src/net/mcast/CMakeLists.txt4
-rw-r--r--src/net/mcast/McastConfiguration.h2
-rw-r--r--src/net/mcast/McastConstants.h3
-rw-r--r--src/net/mcast/McastPGMSocket.cpp323
-rw-r--r--src/net/mcast/McastPGMSocket.h5
-rw-r--r--src/net/mcast/McastSender.cpp44
-rw-r--r--src/net/mcast/McastSender.h1
-rw-r--r--src/net/mcast/trial_programs/mcastsend.cpp3
8 files changed, 195 insertions, 190 deletions
diff --git a/src/net/mcast/CMakeLists.txt b/src/net/mcast/CMakeLists.txt
index e418c64..914c9d3 100644
--- a/src/net/mcast/CMakeLists.txt
+++ b/src/net/mcast/CMakeLists.txt
@@ -34,10 +34,6 @@ SET(pvsmcast_SRCS
McastSender.cpp
)
-INCLUDE_DIRECTORIES(
- ${CMAKE_BINARY_DIR}/3rdparty/libpgm-src/openpgm/pgm/include
-)
-
QT4_WRAP_CPP(
pvsmcast_MOC_SRCS
${pvsmcast_MOC_HDRS}
diff --git a/src/net/mcast/McastConfiguration.h b/src/net/mcast/McastConfiguration.h
index 4e0e2ad..f10d487 100644
--- a/src/net/mcast/McastConfiguration.h
+++ b/src/net/mcast/McastConfiguration.h
@@ -156,7 +156,7 @@ public:
quint16 multicastUDPMPort() const
{
- return _multicastUDPPortBase + 1;
+ return _multicastUDPPortBase;
}
void commit()
diff --git a/src/net/mcast/McastConstants.h b/src/net/mcast/McastConstants.h
index b4c71a5..624e195 100644
--- a/src/net/mcast/McastConstants.h
+++ b/src/net/mcast/McastConstants.h
@@ -26,10 +26,11 @@
#define DEFAULT_MULTICAST_DPORT 6965
#define DEFAULT_MULTICAST_USEUDP true
#define DEFAULT_MULTICAST_UDPPORT 6966
+#define DEFAULT_MULTICAST_WSIZ 30
#define DEFAULT_MULTICAST_RATE (100*1024)
-#define DEFAULT_MULTICAST_WSIZ 3000
#define DEFAULT_MULTICAST_MTU 1400
#define DEFAULT_MULTICAST_APDU 1200
#define DEFAULT_MULTICAST_CHUNK 1024
+#define DEFAULT_MULTICAST_SHUTDOWN_TIMEOUT 10000
#endif /* MCASTMAGIC_H_ */
diff --git a/src/net/mcast/McastPGMSocket.cpp b/src/net/mcast/McastPGMSocket.cpp
index ba51444..8aee209 100644
--- a/src/net/mcast/McastPGMSocket.cpp
+++ b/src/net/mcast/McastPGMSocket.cpp
@@ -16,31 +16,27 @@
#include <cstdlib>
+#include <sys/poll.h>
+#include <sys/socket.h>
+
#include <QByteArray>
+#include <QList>
#include <QtDebug>
#include <QPointer>
#include <QSocketNotifier>
#include <QTimer>
#include <pgm/pgm.h>
-// #include <stdint.h>
-// #define SIZE_MAX UINT64_MAX
-// #include <impl/socket.h>
-// pgm redefined bool to int. Undo that.
-#undef bool
-
-#include <sys/poll.h>
#include "McastPGMSocket.h"
+using namespace std;
+
class McastPGMSocket_priv
{
public:
McastPGMSocket_priv() :
socket(0),
- recv_notif(0),
- repair_notif(0),
- pending_notif(0),
send_notif(0)
{
}
@@ -48,37 +44,28 @@ public:
{
if (socket)
pgm_close(socket, 0);
- if (recv_notif)
- delete recv_notif;
- if (repair_notif)
- delete repair_notif;
- if (pending_notif)
- delete pending_notif;
+ Q_FOREACH(QSocketNotifier* notif, _notifs)
+ {
+ delete notif;
+ }
if (send_notif)
delete send_notif;
}
pgm_sock_t* socket;
McastPGMSocket::Direction direction;
- QSocketNotifier* recv_notif;
- QSocketNotifier* repair_notif;
- QSocketNotifier* pending_notif;
QSocketNotifier* send_notif;
+ QList<QSocketNotifier*> _notifs;
QSocketNotifier* notifier_for(int fd) {
- if (recv_notif && (fd == recv_notif->socket()))
- {
- return recv_notif;
- }
- else if (repair_notif && (fd == repair_notif->socket()))
- {
- return repair_notif;
- }
- else if (pending_notif && (fd == pending_notif->socket()))
- {
- return pending_notif;
- }
- return 0;
+ Q_FOREACH(QSocketNotifier* notif, _notifs)
+ {
+ if(notif->socket() == fd)
+ {
+ return notif;
+ }
+ }
+ return 0;
}
};
@@ -102,7 +89,9 @@ McastPGMSocket::McastPGMSocket(QObject* parent) :
_finished(false),
_nakTimeout(new QTimer()),
_dataTimeout(new QTimer()),
- _sendTimeout(new QTimer())
+ _sendTimeout(new QTimer()),
+ _shutdownTimer(0),
+ _shutdown_timeout(0)
{
_ensurePGMInited();
@@ -166,9 +155,11 @@ bool McastPGMSocket::open(McastConfiguration const* config, Direction direction)
// write-only socket
const int send_only = 1,
spm_heartbeat[] =
- { 16 * 1000, 16 * 1000, 16 * 1000, 16 * 1000, 32 * 1000, 64 * 1000, 128
- * 1000, 256 * 1000, 512 * 1000, 1024 * 1000, 2048 * 1000, 4096
- * 1000 },
+ { 256 * 1000,
+ 512 * 1000,
+ 1024 * 1000,
+ 2048 * 1000,
+ 4096 * 1000 },
max_rate = config->multicastRate(),
max_window = config->multicastWinSize();
// const int max_window_sqns = 3000;
@@ -182,8 +173,8 @@ bool McastPGMSocket::open(McastConfiguration const* config, Direction direction)
// Transmit window
pgm_setsockopt(_priv->socket, PGM_TXW_MAX_RTE, &max_rate, sizeof(max_rate));
- // pgm_setsockopt(_priv->socket, PGM_TXW_SECS, &max_window, sizeof(max_window));
- pgm_setsockopt(_priv->socket, PGM_TXW_SQNS, &max_window, sizeof(max_window));
+ pgm_setsockopt(_priv->socket, PGM_TXW_SECS, &max_window, sizeof(max_window));
+ // pgm_setsockopt(_priv->socket, PGM_TXW_SQNS, &max_window, sizeof(max_window));
}
else
{
@@ -191,41 +182,36 @@ bool McastPGMSocket::open(McastConfiguration const* config, Direction direction)
const int recv_only = 1,
passive = 0,
max_window = config->multicastWinSize(),
- max_winsqns = 0,
+ max_rate = config->multicastRate(),
peer_expiry = ambient_spm * 5,
spmr_expiry = 250 * 1000,
nak_bo_ivl = 100 * 1000,
- nak_rpt_ivl = 100 * 1000,
- nak_rdata_ivl = 200 * 1000,
+ nak_rpt_ivl = 400 * 1000,
+ nak_rdata_ivl = 400 * 1000,
nak_data_retries = 50,
- nak_ncf_retries = 50;
+ nak_ncf_retries = 50,
+ no_rxw_sqns = 0;
pgm_setsockopt(_priv->socket, PGM_RECV_ONLY, &recv_only, sizeof(recv_only));
pgm_setsockopt(_priv->socket, PGM_PASSIVE, &passive, sizeof(passive));
- // pgm_setsockopt(_priv->socket, PGM_RXW_SECS, &max_window, sizeof(max_window));
- pgm_setsockopt(_priv->socket, PGM_RXW_SQNS, &max_window, sizeof(max_window));
+ pgm_setsockopt(_priv->socket, PGM_RXW_MAX_RTE, &max_rate, sizeof(max_rate));
+ pgm_setsockopt(_priv->socket, PGM_RXW_SECS, &max_window, sizeof(max_window));
+ pgm_setsockopt(_priv->socket, PGM_SPMR_EXPIRY, &spmr_expiry, sizeof(spmr_expiry));
pgm_setsockopt(_priv->socket, PGM_PEER_EXPIRY, &peer_expiry, sizeof(peer_expiry));
- pgm_setsockopt(_priv->socket, PGM_SPMR_EXPIRY, &spmr_expiry, sizeof(spmr_expiry));
pgm_setsockopt(_priv->socket, PGM_NAK_BO_IVL, &nak_bo_ivl, sizeof(nak_bo_ivl));
pgm_setsockopt(_priv->socket, PGM_NAK_RPT_IVL, &nak_rpt_ivl, sizeof(nak_rpt_ivl));
pgm_setsockopt(_priv->socket, PGM_NAK_RDATA_IVL, &nak_rdata_ivl, sizeof(nak_rdata_ivl));
pgm_setsockopt(_priv->socket, PGM_NAK_DATA_RETRIES, &nak_data_retries, sizeof(nak_data_retries));
pgm_setsockopt(_priv->socket, PGM_NAK_NCF_RETRIES, &nak_ncf_retries, sizeof(nak_ncf_retries));
+ pgm_setsockopt(_priv->socket, PGM_RXW_SQNS, &no_rxw_sqns, sizeof(no_rxw_sqns));
}
- // MTU
+ const int use_pgmcc = 1;
+ pgm_setsockopt(_priv->socket, PGM_USE_PGMCC, &use_pgmcc, sizeof(use_pgmcc));
+
+ // MTU
int const mtu = config->multicastMTU();
pgm_setsockopt(_priv->socket, PGM_MTU, &mtu, sizeof(mtu));
- // UDP Encapsulation
- if(config->multicastUseUDP())
- {
- const quint16 uport = config->multicastUDPUPort();
- const quint16 mport = config->multicastUDPMPort();
-
- pgm_setsockopt(_priv->socket, PGM_UDP_ENCAP_MCAST_PORT, &mport, sizeof(mport));
- pgm_setsockopt(_priv->socket, PGM_UDP_ENCAP_UCAST_PORT, &uport, sizeof(uport));
- }
-
pgm_sockaddr_t addr;
addr.sa_addr.sport = config->multicastSPort();
addr.sa_port = config->multicastDPort();
@@ -237,7 +223,25 @@ bool McastPGMSocket::open(McastConfiguration const* config, Direction direction)
return false;
}
- good = pgm_bind3(_priv->socket, &addr, sizeof(addr), (struct group_req*)&addrinfo->ai_send_addrs[0], sizeof(struct group_req), (struct group_req*)&addrinfo->ai_recv_addrs[0], sizeof(struct group_req), &err);
+ struct pgm_interface_req_t ifreq;
+ ifreq.ir_interface = addrinfo->ai_send_addrs[0].gsr_interface;
+ ifreq.ir_scope_id = 0;
+ if (AF_INET6 == family)
+ {
+ ifreq.ir_scope_id = ((struct sockaddr_in6*)&addrinfo->ai_send_addrs[0])->sin6_scope_id;
+ }
+
+ // UDP Encapsulation
+ if(config->multicastUseUDP())
+ {
+ const int uport = config->multicastUDPUPort();
+ const int mport = config->multicastUDPMPort();
+
+ pgm_setsockopt(_priv->socket, PGM_UDP_ENCAP_MCAST_PORT, &mport, sizeof(mport));
+ pgm_setsockopt(_priv->socket, PGM_UDP_ENCAP_UCAST_PORT, &uport, sizeof(uport));
+ }
+
+ good = pgm_bind3(_priv->socket, &addr, sizeof(addr), &ifreq , sizeof(ifreq), &ifreq, sizeof(ifreq), &err);
if (!good)
{
qCritical() << "Could not bind socket: PGM Error: " << err->message;
@@ -290,20 +294,15 @@ void McastPGMSocket::setupNotifiers()
int recv_sock, repair_sock, pending_sock;
char const* slotname = (_priv->direction == PSOCK_WRITE) ? SLOT(handleNak(int)) : SLOT(handleData(int));
- pgm_getsockopt(_priv->socket, PGM_RECV_SOCK, &recv_sock, sizeof(recv_sock));
- _priv->recv_notif = new QSocketNotifier(recv_sock, QSocketNotifier::Read,
- this);
- connect(_priv->recv_notif, SIGNAL(activated(int)), this, slotname);
-
- pgm_getsockopt(_priv->socket, PGM_REPAIR_SOCK, &repair_sock, sizeof(repair_sock));
- _priv->repair_notif = new QSocketNotifier(repair_sock,
- QSocketNotifier::Read, this);
- connect(_priv->repair_notif, SIGNAL(activated(int)), this, slotname);
-
- pgm_getsockopt(_priv->socket, PGM_PENDING_SOCK, &pending_sock, sizeof(pending_sock));
- _priv->pending_notif = new QSocketNotifier(pending_sock,
- QSocketNotifier::Read, this);
- connect(_priv->pending_notif, SIGNAL(activated(int)), this, slotname);
+ struct pollfd pollin[10];
+ int in_nfds = 10;
+ pgm_poll_info(_priv->socket, pollin, &in_nfds, POLLIN);
+ for(int i = 0; i < in_nfds; i++)
+ {
+ QSocketNotifier* notif = new QSocketNotifier(pollin[i].fd, QSocketNotifier::Read, this);
+ _priv->_notifs.append(notif);
+ connect(notif, SIGNAL(activated(int)), this, slotname);
+ }
if(_priv->direction == PSOCK_WRITE)
{
@@ -317,11 +316,17 @@ void McastPGMSocket::setupNotifiers()
void McastPGMSocket::handleNak(int fd)
{
- qDebug() << "handleNak(int)";
+ qDebug() << "handleNak(" << fd << ")";
QSocketNotifier* notif = _priv->notifier_for(fd);
notif->setEnabled(false);
+ if (_shutdownTimer)
+ {
+ _shutdownTimer->start(_shutdown_timeout);
+ qDebug() << "Started shutdown timer";
+ }
+
handleNak();
notif->setEnabled(true);
@@ -334,7 +339,7 @@ void McastPGMSocket::handleNak()
qDebug() << "handleNak()";
- QTimer::singleShot(1000, this, SLOT(handleNakTimeout()));
+ // QTimer::singleShot(1000, this, SLOT(handleNakTimeout()));
// to handle NAKs in OpenPGM, we need to pgm_recv:
char buf[4096];
@@ -349,7 +354,8 @@ void McastPGMSocket::handleNak()
if(status == PGM_IO_STATUS_TIMER_PENDING)
{
struct timeval tv;
- pgm_getsockopt(_priv->socket, PGM_TIME_REMAIN, &tv, sizeof(tv));
+ socklen_t size = sizeof(tv);
+ pgm_getsockopt(_priv->socket, PGM_TIME_REMAIN, &tv, &size);
const int msecs = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
qDebug() << " timer pending: " << msecs << "ms";
_nakTimeout->start(msecs);
@@ -358,7 +364,8 @@ void McastPGMSocket::handleNak()
else if(status == PGM_IO_STATUS_RATE_LIMITED)
{
struct timeval tv;
- pgm_getsockopt(_priv->socket, PGM_RATE_REMAIN, &tv, sizeof(tv));
+ socklen_t size = sizeof(tv);
+ pgm_getsockopt(_priv->socket, PGM_RATE_REMAIN, &tv, &size);
const int msecs = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
qDebug() << " rate limited: " << msecs << "ms";
_nakTimeout->start(msecs);
@@ -437,7 +444,8 @@ void McastPGMSocket::handleData()
else if (status == PGM_IO_STATUS_TIMER_PENDING)
{
struct timeval tv;
- pgm_getsockopt(_priv->socket, PGM_TIME_REMAIN, &tv, sizeof(tv));
+ socklen_t size = sizeof(tv);
+ pgm_getsockopt(_priv->socket, PGM_TIME_REMAIN, &tv, &size);
const int msecs = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
qDebug() << " timer pending: " << msecs << "ms";
_dataTimeout->start(msecs);
@@ -446,7 +454,8 @@ void McastPGMSocket::handleData()
else if (status == PGM_IO_STATUS_RATE_LIMITED)
{
struct timeval tv;
- pgm_getsockopt(_priv->socket, PGM_RATE_REMAIN, &tv, sizeof(tv));
+ socklen_t size = sizeof(tv);
+ pgm_getsockopt(_priv->socket, PGM_RATE_REMAIN, &tv, &size);
const int msecs = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
qDebug() << " rate limit pending: " << msecs << "ms";
_dataTimeout->start(msecs);
@@ -493,113 +502,80 @@ void McastPGMSocket::canSend()
if (_finished)
return;
- qDebug() << "canSend()";
+ // qDebug() << "canSend()";
if (_priv->send_notif)
{
_priv->send_notif->setEnabled(false);
}
- bool reenable = true;
-
- while (!_q.isEmpty())
- {
- int status;
- QByteArray const nextPacket(_q.head());
- status = pgm_send(_priv->socket, nextPacket.constData(), nextPacket.size(), 0);
- if (status == PGM_IO_STATUS_ERROR || status == PGM_IO_STATUS_RESET)
- {
- qCritical() << "Could not send packet: PGM Error.";
- continue;
- }
- else if (status == PGM_IO_STATUS_WOULD_BLOCK)
- {
- qDebug() << " would block";
- break;
- }
- else if (status == PGM_IO_STATUS_RATE_LIMITED)
- {
- struct timeval tv;
- pgm_getsockopt(_priv->socket, PGM_RATE_REMAIN, &tv, sizeof(tv));
- const int msecs = (tv.tv_sec * 1000) + (tv.tv_usec / 1000);
- qDebug() << " rate limited:" << msecs << "ms";
- _sendTimeout->start((msecs > 0) ? msecs : 1);
- reenable = false;
- break;
- }
- else if (status == PGM_IO_STATUS_NORMAL)
- {
- qDebug() << " sent";
- _q.dequeue();
- continue;
- }
- else
- {
- qCritical() << "Unhandled condition in McastPGMSocket::canSend()";
- }
- }
-
- if (_priv->send_notif && reenable)
+ if(_q.isEmpty())
{
- emit readyToSend();
+ emit readyToSend();
+ }
+ else
+ {
+ QByteArray const packet(_q.head());
+ int status;
+
+ status = pgm_send(_priv->socket, packet.constData(), packet.size(), 0);
- qDebug() << " reenable notifier";
- _priv->send_notif->setEnabled(true);
+ if(status == PGM_IO_STATUS_NORMAL)
+ {
+ _q.dequeue();
+ if(!_q.isEmpty())
+ {
+ _priv->send_notif->setEnabled(true);
+ }
+ else
+ {
+ emit readyToSend();
+ }
+ }
+ else if(status == PGM_IO_STATUS_WOULD_BLOCK)
+ {
+ _priv->send_notif->setEnabled(true);
+ }
+ else if(status == PGM_IO_STATUS_RATE_LIMITED)
+ {
+ struct timeval tv;
+ socklen_t size = sizeof(tv);
+ pgm_getsockopt(_priv->socket, PGM_RATE_REMAIN, &tv, &size);
+ int msecs = (tv.tv_sec * 1000) + ((tv.tv_sec + 999) / 1000);
+ _sendTimeout->start(msecs);
+ }
+ else
+ {
+ qCritical() << "Unhandled status in canSend()";
+ }
}
+
+ if (_shutdownTimer)
+ _shutdownTimer->start(_shutdown_timeout);
}
void McastPGMSocket::sendPacket(QByteArray const& bytes)
{
- if(_q.isEmpty())
- {
- int status = pgm_send(_priv->socket, bytes.constData(), bytes.size(), 0);
+ if(_shutdownTimer)
+ {
+ qCritical() << "Logic error: sendPacket() after shutdown()";
+ }
- if (status == PGM_IO_STATUS_ERROR || status == PGM_IO_STATUS_RESET)
- {
- qCritical() << "Could not send packet: PGM Error.";
- return;
- }
- else if (status == PGM_IO_STATUS_WOULD_BLOCK)
- {
- _q.enqueue(bytes);
- }
- else if (status == PGM_IO_STATUS_RATE_LIMITED)
- {
- _q.enqueue(bytes);
- struct timeval tv;
- pgm_getsockopt(_priv->socket, PGM_RATE_REMAIN, &tv, sizeof(tv));
- _dataTimeout->start((tv.tv_sec * 1000) + (tv.tv_usec / 1000));
- }
- else if (status == PGM_IO_STATUS_NORMAL)
- {
- return;
- }
- else
- {
- qCritical() << "Unhandled condition in McastPGMSocket::sendPacket()";
- }
- } else {
- _q.enqueue(bytes);
- }
+ _q.enqueue(bytes);
+ _priv->send_notif->setEnabled(true);
}
void McastPGMSocket::finish()
{
- if(_priv->pending_notif)
- {
- delete _priv->pending_notif;
- _priv->pending_notif = 0;
- }
- if(_priv->recv_notif)
- {
- delete _priv->recv_notif;
- _priv->recv_notif = 0;
- }
- if(_priv->repair_notif)
+ qDebug() << "finish()";
+
+ Q_FOREACH(QSocketNotifier* notif, _priv->_notifs)
{
- delete _priv->repair_notif;
- _priv->repair_notif = 0;
+ notif->setEnabled(false);
+ delete notif;
}
+ _priv->_notifs.clear();
+
if(_priv->send_notif)
{
delete _priv->send_notif;
@@ -610,9 +586,28 @@ void McastPGMSocket::finish()
_priv->socket = 0;
_finished = true;
+
+ emit connectionFinished();
+
+ qDebug() << "Socket finished";
}
bool McastPGMSocket::finished() const
{
return _finished;
}
+
+void McastPGMSocket::shutdown(int interval)
+{
+ if(_priv->direction == PSOCK_READ)
+ return;
+
+ _shutdown_timeout = interval;
+ _shutdownTimer = new QTimer(this);
+ connect(_shutdownTimer, SIGNAL(timeout()), this, SLOT(finish()));
+ if (_q.isEmpty())
+ {
+ _shutdownTimer->start(_shutdown_timeout);
+ qDebug() << "Started shutdown timer";
+ }
+}
diff --git a/src/net/mcast/McastPGMSocket.h b/src/net/mcast/McastPGMSocket.h
index b0007a7..ad42aa5 100644
--- a/src/net/mcast/McastPGMSocket.h
+++ b/src/net/mcast/McastPGMSocket.h
@@ -22,6 +22,7 @@
#include <QQueue>
#include <src/net/mcast/McastConfiguration.h>
+#include <src/net/mcast/McastConstants.h>
class McastPGMSocket_priv;
class QTimer;
@@ -40,12 +41,14 @@ public:
bool open(McastConfiguration const* config, Direction direction);
bool finished() const;
+ void shutdown(int interval = DEFAULT_MULTICAST_SHUTDOWN_TIMEOUT);
signals:
void readyToSend();
void receivedPacket(QByteArray const& bytes);
void connectionReset();
void connectionFinished();
+ void shutdownComplete();
public slots:
void sendPacket(QByteArray const& bytes);
@@ -67,6 +70,8 @@ private:
QTimer* _nakTimeout;
QTimer* _dataTimeout;
QTimer* _sendTimeout;
+ QTimer* _shutdownTimer;
+ int _shutdown_timeout;
void setupNotifiers();
};
diff --git a/src/net/mcast/McastSender.cpp b/src/net/mcast/McastSender.cpp
index 24a629c..f49c0df 100644
--- a/src/net/mcast/McastSender.cpp
+++ b/src/net/mcast/McastSender.cpp
@@ -61,36 +61,44 @@ void McastSender::readyToSend()
strm << qChecksum(fpdu.constData(), fpdu.size());
_socket->sendPacket(fpdu);
- // _socket->finish();
+ connect(_socket, SIGNAL(connectionFinished()), this, SLOT(socketFinished()));
+ _socket->shutdown();
_finished = true;
- emit finished();
- return;
+ _iodev->close();
}
+ else
+ {
+ QByteArray barr(DEFAULT_MULTICAST_APDU, '\0');
+ qint64 len_read;
+ len_read = _iodev->read(barr.data(), barr.capacity());
+ barr.resize((int)len_read);
- QByteArray barr(DEFAULT_MULTICAST_APDU, '\0');
- qint64 len_read;
- len_read = _iodev->read(barr.data(), barr.capacity());
- barr.resize((int)len_read);
-
- _hash.addData(barr);
+ _hash.addData(barr);
- QByteArray pdu;
- QDataStream strm(&pdu, QIODevice::WriteOnly);
- strm.setByteOrder(QDataStream::BigEndian);
+ QByteArray pdu;
+ QDataStream strm(&pdu, QIODevice::WriteOnly);
+ strm.setByteOrder(QDataStream::BigEndian);
- strm << (quint64)MCASTFT_MAGIC << _curoffs;
- strm << barr;
- quint16 checksum = qChecksum(pdu.constData(), pdu.size());
- strm << checksum;
+ strm << (quint64)MCASTFT_MAGIC << _curoffs;
+ strm << barr;
+ quint16 checksum = qChecksum(pdu.constData(), pdu.size());
+ strm << checksum;
- _curoffs += len_read;
+ _curoffs += len_read;
- _socket->sendPacket(pdu);
+ _socket->sendPacket(pdu);
+ }
}
void McastSender::close()
{
_socket->finish();
}
+
+void McastSender::socketFinished()
+{
+ delete _socket;
+ emit finished();
+}
diff --git a/src/net/mcast/McastSender.h b/src/net/mcast/McastSender.h
index e713886..5c62fad 100644
--- a/src/net/mcast/McastSender.h
+++ b/src/net/mcast/McastSender.h
@@ -55,6 +55,7 @@ public slots:
private slots:
void readyToSend();
+ void socketFinished();
private:
McastConfiguration* _config;
diff --git a/src/net/mcast/trial_programs/mcastsend.cpp b/src/net/mcast/trial_programs/mcastsend.cpp
index da8ecf4..f78a9ce 100644
--- a/src/net/mcast/trial_programs/mcastsend.cpp
+++ b/src/net/mcast/trial_programs/mcastsend.cpp
@@ -118,6 +118,5 @@ void McastSend::run()
void McastSend::finished()
{
cerr << "finished." << endl;
- // QTimer::singleShot(30000, QCoreApplication::instance(), SLOT(quit()));
- // QCoreApplication::quit();
+ QCoreApplication::quit();
}