⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 largedatagramout.cpp

📁 用qt4 编写的局域网聊天工具
💻 CPP
字号:
/*************************************************************************** *   Copyright (C) 2007 by Anistratov Oleg                                 * *   ower@users.sourceforge.net                                            * *                                                                         * *   This program is free software; you can redistribute it and/or modify  * *   it under the terms of the GNU General Public License version 2        * *   as published by the Free Software Foundation;                         * *                                                                         * *   This program 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.                          * *                                                                         * ***************************************************************************/#include "largedatagramout.h"#include <QThread>#include "chatcore.h"LargeDatagramOut::LargeDatagramOut(QObject *parent) : QObject(parent),  m_confirmed          (false),  m_inited             (false),  m_header             (NULL),  m_data               (NULL),  m_fragments          (NULL),  m_selfDestroyInterval(10 * 1000){  m_selfDestroyTimer = new QTimer(this);  connect(m_selfDestroyTimer, SIGNAL(timeout()), this, SLOT(selfDestroy()));}//\*****************************************************************************LargeDatagramOut::~LargeDatagramOut(){  qDebug("[~LargeDatagramOut]: ID = %lu", (unsigned long)m_id);  free(m_header); // we need free only m_header beckause m_data points to m_header + m_headerSize  free(m_fragments);}//\*****************************************************************************void LargeDatagramOut::init(char* header, quint16 header_size,                            char* data  , quint32 data_size  , quint64 dest_uid, quint32 id){  m_id              = id;  m_header          = header;  m_data            = data  ;  m_headerSize      = header_size;  m_dataSize        = data_size;  m_sizePerFragment = (MAX_PACKET_LEN - m_headerSize);  m_rest            = m_dataSize % m_sizePerFragment;  m_totalFragments  = m_dataSize / m_sizePerFragment + m_rest;  m_fragmentsRemain = m_totalFragments;  m_fragments       = (char*)calloc(m_totalFragments + 1, 1);// + 1, beckause we need to send initialization packet  m_inited          = true;  m_confirmed       = true;  m_destUid         = dest_uid;}//\*****************************************************************************void LargeDatagramOut::init(char*   header, quint16 header_size,                            const QString & filename, quint64 dest_uid, quint32 id){  m_id         = id;  m_header     = header;  m_data       = NULL;  m_headerSize = header_size;  m_dataSize   = 0;  m_filename   = filename;  m_destUid    = dest_uid;  m_file.setFileName(filename);  if(!m_file.open(QIODevice::ReadOnly))  {    qWarning("[LargeDatagramOut::init]: Failed. couldn't open file %s for reading!\n", m_filename.toLocal8Bit().data());    emit wantDie(this);    emit sendingCancelled(id);    return;  }  if(m_file.handle() < 0)  {    qWarning("[LargeDatagramOut::init]: m_file.handle() < 0\n");//     emit wantDie(this);//     return;  }  m_fileSize        = m_file.size();  m_sizePerFragment = (MAX_PACKET_LEN - m_headerSize);  m_rest            = m_fileSize % m_sizePerFragment;  m_totalFragments  = m_fileSize / m_sizePerFragment + m_rest;  m_fragmentsRemain = m_totalFragments;  m_fragments       = (char*)calloc(m_totalFragments + 1, 1);// + 1, t.k. nado otoslat' esche i initsializir. paket!  m_inited          = true;}//\*****************************************************************************void LargeDatagramOut::prepareInitHeader(){  if(!m_inited)    return;  AbstractChatCore::setPacketId    (m_header, m_id);  AbstractChatCore::setFragmentSize(m_header, m_sizePerFragment);  AbstractChatCore::setPacketNum   (m_header, 0);  AbstractChatCore::setMessageLen  (m_header, m_totalFragments); // +61 MsgLen        / TotalFragments / DataLen  // FIXME !!!file size may be greater then quint32!!!  if(!m_filename.isEmpty())    AbstractChatCore::setParametrsLen(m_header, m_fileSize);  else    AbstractChatCore::setParametrsLen(m_header, m_dataSize); // +65 ParametersLen / TotalSize      / == 0}//\*****************************************************************************void LargeDatagramOut::sendNextFragment(QAbstractSocket* socket, quint16 port, char* buf){  quint32 num;  quint32 i;  quint32 size;  int res = -1;  QTcpSocket* tcp = qobject_cast<QTcpSocket*>(socket);  QUdpSocket* udp = qobject_cast<QUdpSocket*>(socket);  if(!m_fragmentsRemain)  {    if(m_selfDestroyTimer && (m_selfDestroyTimer->timerId() < 0))    {      m_selfDestroyTimer->setSingleShot(true);      m_selfDestroyTimer->start(m_selfDestroyInterval);    }    return;  }  // TODO optimizirovat'  for(i = 0; i <= m_totalFragments; i++)    if(m_fragments[i] == 0)      break;  num = i;  if(num != 0 && !m_confirmed)    return;  if(num > m_totalFragments)// znachit net neotoslannyh fragmentov. i soobschenii o peresylke ne prihodilo    return;  size = writeFragment(buf, num);  if(tcp)  {    AbstractChatCore::setPacketSize(buf, size);    res = tcp->write(buf, size);    tcp->flush();  }  else if(udp)    res = udp->writeDatagram(buf, size, QHostAddress(m_destUid), port);  if(res < 0)    qWarning("\n[LargeDatagramOut::sendNextFragment]: datagram send error !\n");  else  {    m_fragments[num] = 1;    if(num)      m_fragmentsRemain--;    // esli vse otoslali - zhdem nekotoroe vremya zaprosov pereslat' zanovo fragmenty,    // i esli zaprosa ne prihodit unichtozhaemsya    if(!m_fragmentsRemain)    {      m_selfDestroyTimer->setSingleShot(true);      m_selfDestroyTimer->start(m_selfDestroyInterval);    }  }}//\*****************************************************************************quint32 LargeDatagramOut::writeFragment(char* buf, quint32 num){  if(!m_inited || !buf || num > m_totalFragments)    return 0;  uint fragmentSize = m_sizePerFragment;  if(num == m_totalFragments && m_rest)    if(!m_filename.isEmpty())      fragmentSize = m_fileSize % m_sizePerFragment;    else      fragmentSize = m_dataSize % m_sizePerFragment;  if(!num)  {    prepareInitHeader();    memcpy(buf, m_header, m_headerSize);    if(!m_filename.isEmpty())    {      QByteArray ba = m_filename.right(m_filename.size() - 1 - m_filename.lastIndexOf("/")).toUtf8();      catUS2str(buf + m_headerSize, ba.size());      memcpy(buf + m_headerSize + 2, ba.data(), ba.size());      return m_headerSize + 2 + ba.size();    }    return m_headerSize;  }  AbstractChatCore::setParametrsLen(m_header, 0); // +65 ParametersLen / TotalSize      / == 0  AbstractChatCore::setPacketNum   (m_header, num); //PacketNUM  AbstractChatCore::setMessageLen  (m_header, m_sizePerFragment); // +61 MsgLen        / TotalFragments / DataLen  memcpy(buf, m_header, m_headerSize);  if(!m_filename.isEmpty())  {    m_file.seek((num - 1) * m_sizePerFragment);    m_file.read(buf + m_headerSize, fragmentSize);    return m_headerSize + fragmentSize;  }  memcpy(buf + m_headerSize, m_data + (m_sizePerFragment * (num - 1)), fragmentSize);  return m_headerSize + fragmentSize;}//\*****************************************************************************void LargeDatagramOut::selfDestroy(){  qDebug("[LargeDatagramOut[%d]::selfDestroy]", m_id);  emit wantDie(this);}//\*****************************************************************************void LargeDatagramOut::slot_confirmed(unsigned short ID){  if(m_id == ID)    m_confirmed = true;}//\*****************************************************************************void LargeDatagramOut::fragmentsRequest(const char* dtgrm, quint16 len){//   qDebug("[LargeDatagramOut::fragmentsRequest]");  quint32 i;  quint32 shift;  quint32 pars_len = AbstractChatCore::parametrsLen(dtgrm);  shift = AbstractChatCore::compNameLen(dtgrm) + AbstractChatCore::protocolLen() +          AbstractChatCore::userNameLen(dtgrm) + AbstractChatCore::messageLen(dtgrm) + AbstractChatCore::optionsLen(dtgrm);  if(len - shift < pars_len)    return;  QByteArray  pars(dtgrm + shift, pars_len);  QByteArray  buf;  quint16     frags_len;  const char* frags;  if(!m_inited)    return;  buf       = ChatCore::getParametr("FragmentsLen", pars);  frags_len = str2US(buf.data());  qDebug("[LargeDatagramOut::fragmentsRequest]: fragments_len = %d", frags_len);  buf       = ChatCore::getParametr("FragmentsRequest", pars);  frags     = buf.constData();  qDebug("[LargeDatagramOut::fragmentsRequest]: fragmentsRemain before = %d", m_fragmentsRemain);  for(i = 0; i < frags_len && i < m_totalFragments; i++)    if(!frags[i])    {      m_fragmentsRemain += m_fragments[i + 1];      m_fragments[i + 1] = 0;    }  qDebug("[LargeDatagramOut::fragmentsRequest]: fragmentsRemain after  = %d", m_fragmentsRemain);  if(m_fragmentsRemain)    m_selfDestroyTimer->stop();}//\*****************************************************************************

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -