16,816
社区成员




//tcpserver.h
#ifndef TCPSERVER_H
#define TCPSERVER_H
#include "tcpthread.h"
#include <QTcpServer>
class tcpserver : public QTcpServer
{
Q_OBJECT
public:
explicit tcpserver(QObject *parent = 0);
//QList<int> clientDescriptorList;
signals:
void newRow(int);
void displayInfo(int,QString, int);
void updateBar(int, qint64);
void signal_send_command(int,int);
public slots:
void incomingConnection(int socketDescriptor);
void slot_send_command(int,int);
};
#endif
//tcpthread.h
#ifndef TCPTHREAD_H
#define TCPTHREAD_H
#include <QThread>
#include <QTcpSocket>
#include <QtNetwork>
#define SEND_AGIAN 2
#define FOUND_FINISH 3
#define SEND_SUCCESS 4
#define SEND_GET 10
#define FOUND_START 11
#define TEST_OTHER 98
#define DISPLAY_BUFFER 97
#define RECV_FILE_SUCCESS 99
#define SAVE_FILE_SUCCESS 100
#define GET "GET"
#define START "START"
#define AGAIN "AGIAN"
#define FINISH "FINISH"
#define SUCCESS "SUCCESS"
class QFile;
class QTcpSocket;
class TcpThread : public QThread
{
Q_OBJECT
public:
TcpThread(int socketDescriptor,int command, QObject *parent = 0);
void run();
QTcpSocket *sockfd;
int socketDescriptor;
int command;
signals:
void error(QTcpSocket::SocketError socketError);
void displayInfo(int,QString, int);
void updateBar(int, qint64);
public slots:
int processBuffer(QString );
void recvData();
};
#endif // TCPTHREAD_H
//widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include "tcpthread.h"
#include "tcpserver.h"
class QDialogButtonBox;
class QTcpSocket;
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
TcpThread *thread ;
private:
Ui::Widget *ui;
tcpserver tcpServer;
QTime *currenttime;
private slots:
void on_pushButtonClearLog_clicked();
void on_pushButtonSaveLog_clicked();
void on_quitButton_clicked();
void on_pushButtonGET_clicked();
void on_OkButton_clicked();
void addNewRow(int);
void displayInfo(int,QString, int);
void updateBar(int, qint64);
signals:
void signal_send_command(int, int);
};
#endif // WIDGET_H
//tcpserver.cpp
#include "tcpserver.h"
//构造函数
tcpserver::tcpserver(QObject *parent) :
QTcpServer(parent)
{
}
//重新定义了incomingConnection这个虚函数,
//开辟一个新的tcpsocket线程,从TcpServer获得socketDescriptor,
//并完成相应的信号连接
void tcpserver::incomingConnection(int socketDescriptor)
{
qDebug() <<socketDescriptor;
//clientDescriptorList.append(socketDescriptor);
emit newRow(socketDescriptor); //display new client
connect(this,SIGNAL(signal_send_command(int ,int)),this,SLOT(slot_send_command(int ,int)));
}
void tcpserver::slot_send_command(int sockDescriptor, int cmd)
{
TcpThread *thread = new TcpThread(sockDescriptor,cmd, this);
thread->start();
connect(thread,SIGNAL(finished()),this,SLOT(deleteLater()));
connect(thread,SIGNAL(displayInfo(int,QString,int)),this,SIGNAL(displayInfo(int,QString,int)));
connect(thread,SIGNAL(updateBar(int,qint64)),this,SIGNAL(updateBar(int,qint64)));
}
//tcpthread.cpp
#include "tcpthread.h"
#include <QtGui>
#include <QtNetwork>
//构造函数完成简单的赋值/
TcpThread::TcpThread(int socketDescriptor,int command, QObject *parent):
QThread(parent),socketDescriptor(socketDescriptor),command(command)
{
}
void TcpThread::run()
{
sockfd = new QTcpSocket;
if (!sockfd->setSocketDescriptor(socketDescriptor))
{
emit error(sockfd->error());
return;
}
sockfd -> write(GET);
emit this->displayInfo(socketDescriptor,sockfd->peerAddress().toString(), SEND_GET);
connect(sockfd, SIGNAL(readyRead()), this,SLOT(recvData()),Qt::DirectConnection);
exec();
}
void TcpThread::recvData() //接收数据
{
static qint64 bytesReceived = 0 ; //收到的总字节
static QString buffer = ""; //数据缓冲区
qint64 available = 0;
if ( ( available = sockfd ->bytesAvailable() ) > 0 )
{
bytesReceived += available;
buffer.append(sockfd ->readAll());
//更新进度条
emit this->updateBar(socketDescriptor, bytesReceived);
//display buffer
emit this->displayInfo(socketDescriptor,buffer, DISPLAY_BUFFER);
if ( processBuffer(buffer) == 1)
{
emit this->updateBar(socketDescriptor, 100); //更新进度条
goto GOTO_SEND_SUCCESS;
}
goto GOTO_SEND_AGAIN;
GOTO_SEND_SUCCESS:
//send SUCCESS
sockfd -> write(SUCCESS);
emit this-> displayInfo(socketDescriptor,sockfd->peerAddress().toString(), SEND_SUCCESS);
return;
GOTO_SEND_AGAIN:
//send AGIAN
emit this->displayInfo(socketDescriptor,sockfd->peerAddress().toString(), SEND_AGIAN);
if (-1 == sockfd -> write(AGAIN))
{
qDebug() << "write error";
return;
}
}
}
int TcpThread::processBuffer(QString buffer)
{
static int END_FLAG_FINISH = 0 ;
static int positionSTART = 0;
static int positionFINISH = 0;
static QHostAddress fileName ;
static QFile *localFile ;
static QString fileBuffer = ""; //file buffer
END_FLAG_FINISH = 0;
if (-1 != (positionSTART = buffer.indexOf(START)) ) //found START
{
if (-1 != (positionFINISH = buffer.indexOf(FINISH))) //found FINISH
{
emit this->displayInfo(socketDescriptor,sockfd->peerAddress().toString(), FOUND_FINISH);
END_FLAG_FINISH = 1;
fileBuffer = buffer.mid(positionSTART+36,positionFINISH -positionSTART - 36);
fileName = sockfd->peerAddress();
quint16 port = sockfd->peerPort();
localFile = new QFile(fileName.toString()+(tr(".%1").arg(port))); //用户端的IP地址作为保存文件名
if(!localFile->open(QFile::WriteOnly))
{
qDebug() << "open file error!";
return -1;
}
QByteArray filetemp = fileBuffer.toLatin1();
if ( -1 == ( localFile->write(filetemp.data(),qstrlen(filetemp.data()))))
{
qDebug() <<"write file error!";
}
localFile->close();
fileBuffer.clear();
emit this->displayInfo(socketDescriptor,sockfd->peerAddress().toString(), SAVE_FILE_SUCCESS);
return END_FLAG_FINISH;
}
}
return END_FLAG_FINISH;
}
void displayInfo(int,QString, int);
void updateBar(int, qint64);
void FortuneThread::run()
{
QTcpSocket tcpSocket;
if (!tcpSocket.setSocketDescriptor(socketDescriptor)) {
emit error(tcpSocket.error());
return;
}
//...
}
class TcpThread : public QThread
{
//...
}
public slots:
void recvData();
int processBuffer();
connect(sockfd, SIGNAL(readyRead()), this,SLOT(recvData()));