关于QTcpSocket、QTcpServer类的使用

关于QTcpServer服务器的学习
1.创建服务器
创建一个服务器对象;
栈上创建:QTcpServer server;
堆上创建:QTcpServer *server=new QTcpServer;
2.当服务器上有连接的时候,接收对方通信的套接字可以通过以下信号:
当有新的连接时,会自动执行
virtual void incomingConnection(qintptr handle);可以获得socket描述符,将socket描述符存在一个中间变量中。
此时,系统会产生一个newConnection()信号;
3.在设计当中,我们经常会用到自己定义的一些类型,如果也想用signal/slot传递的话,就需要注册类型
(1)首先要包含头文件

#include <QMetaType>

(2)在类型定义完成后,加入声明:Q_DECLARE_METATYPE(类型名称);例如下面代码:

class TextAndNumber {     
public:     
    TextAndNumber();     
    TextAndNumber(int, QString);     
    int count();     
    QString text();     
private:     
    int m_count;     
    QString m_text;     
};     
Q_DECLARE_METATYPE(TextAndNumber);    

(3) 在main()函数中注册这种类型:

qRegisterMetaType<TextAndNumber>("TextAndNumber");

如果还希望使用这种类型的引用,可同样要注册:

qRegisterMetaType<TextAndNumber>("TextAndNumber&");

4.结合堆QTcpSocket和QTcpServer的理解,写了下面一段多线程的服务器
MySocket.h

#ifndef MYSOCKET_H
#define MYSOCKET_H
#include <QTcpSocket>

class MySocket:public QTcpSocket
{
    Q_OBJECT
public:
    MySocket();
public slots:
    void writeData(QByteArray &value);
    void readData();
signals:
    void newData(QByteArray&message,quint16 port,QString &adress);
};

#endif // MYSOCKET_H

MySocket.cpp

#include "mysocket.h"
#include <QHostAddress>
#include <QDebug>
#include <QThread>

MySocket::MySocket()
{

  connect(this,SIGNAL(readyRead()),this,SLOT(readData()),Qt::DirectConnection);
}

void MySocket::writeData(QByteArray &value)
{
    this->write(value);
}

void MySocket::readData()
{
   QByteArray message= this->readAll();
   quint16 port=this->peerPort();
   QString address=this->peerAddress().toString();
   qDebug()<<"readData:"<<QThread::currentThreadId();

   emit this->newData(message,port,address);

}

Myserver.h

#ifndef MYSERVER_H
#define MYSERVER_H
#include <QTcpServer>
#include "mysocket.h"

class MyServer:public QTcpServer
{
    Q_OBJECT
public:
    MyServer();
    bool startServer(QString ip,int port);
protected:
    void incomingConnection(qintptr handle);
signals:
    void serverStarted();
    void newConnected(void* handle);

};

#endif // MYSERVER_H

MyServer.cpp

#include "myserver.h"

MyServer::MyServer()
{


}

bool MyServer::startServer(QString ip,int port)
{
    bool res=false;
    QHostAddress hostAddress=QHostAddress::Any;
    if(ip!="All"){
        hostAddress.setAddress(ip);
    }
    if(this->listen(hostAddress,port)){
        res=true;
        qDebug()<<("Server started ");

    }
    emit serverStarted();
    return res;
}

void MyServer::incomingConnection(qintptr handle)
{
    emit newConnected((void *)handle);
}

threadClient.h

#ifndef THREADCLIENT_H
#define THREADCLIENT_H

#include <QObject>
#include <QThread>
#include "mysocket.h"

class ThreadClient : public QThread
{
    Q_OBJECT
public:
    explicit ThreadClient(QObject *parent = 0);
    void run();

public slots:
    void newData(QByteArray& value,quint16 port ,QString& address);
    void setNewConnection(void * handle);
signals:
    void newDataSiganl(QByteArray &value, quint16 port, QString &address);

private:
    MySocket*socket;
    void *fd;


};

#endif // THREADCLIENT_H

threadClient.cpp

#include "threadclient.h"

ThreadClient::ThreadClient(QObject *parent) : QThread(parent)
{

    fd=NULL;
}

void ThreadClient::run()
{
    socket=new MySocket;
    while(true){
        if(fd!=NULL){
            socket->setSocketDescriptor((qintptr)fd);
            connect(socket,SIGNAL(newData(QByteArray&,quint16,QString&)),
                    this,SLOT(newData(QByteArray&,quint16,QString&)));
            break;
        }
    }
     this->exec();
}


void ThreadClient::newData(QByteArray &value, quint16 port, QString &address)
{

    emit newDataSiganl(value,port,address);
}

void ThreadClient::setNewConnection(void *handle)
{
     fd=(void *) (handle);
}

serverManager.h

#ifndef SERVERMANAGER_H
#define SERVERMANAGER_H

#include <QObject>
#include "myserver.h"
#include "mysocket.h"
#include <QThread>
#include <QHash>
#include "threadclient.h"

class ServerManager: public QObject
{
    Q_OBJECT
public:
    ServerManager();
public slots:
    void newClient();
    void newData(QByteArray& value,quint16 port ,QString& address);
    void newConnection(void * handle);
signals:
    void setNewConnetion(void *handle);
private:
    MyServer*server;
    QHash <int ,QString> clients;
    int num;
    ThreadClient *client;
    void* Connection;

};

#endif // SERVERMANAGER_H

serverManager.cpp

#include "servermanager.h"
#include <QDebug>
#include <QThread>
ServerManager::ServerManager()
{
   qDebug()<<"serverManager:"<<QThread::currentThreadId();
   server=new MyServer;

   connect(server,SIGNAL(newConnected(void *)),this,SLOT(newConnection(void *)),Qt::DirectConnection);
   connect(server,SIGNAL(newConnection()),this,SLOT(newClient()));
   server->startServer("All",6666);
   num=0;
   client=NULL;
}

void ServerManager::newData(QByteArray &message, quint16 port, QString &adress)
{
    qDebug()<<"a new Data: "<<QThread::currentThreadId();
    QString client1=QString::number(port)+":"+adress;
    qDebug()<<message;
    qDebug()<<port<<":"<<adress;
    clients.insert(++num,client1);
}

void ServerManager::newConnection(void *handle)
{
    Connection=handle;
}

void ServerManager::newClient()
{
       client=new ThreadClient;
       connect(this,SIGNAL(setNewConnetion(void *)),client,SLOT(setNewConnection(void*)));
       connect(client,SIGNAL(newDataSiganl(QByteArray&,quint16,QString&)),this,
               SLOT(newData(QByteArray&,quint16,QString&)));
       client->start();
       emit setNewConnetion(Connection);
}

main.cpp

#include <QCoreApplication>
#include "servermanager.h"
#include <QThread>
#include <QDebug>
#include <QByteArray>
#include <QMetaType>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    qRegisterMetaType<QByteArray>("QByteArray &");
    qRegisterMetaType<QString>("QString &");
    ServerManager manager;
    qDebug()<<QThread::currentThreadId();

//    QThread thread;
//    manager.moveToThread(&thread);
//    thread.start();

    return a.exec();
}

猜你喜欢

转载自blog.csdn.net/ninglu1989/article/details/82629352
今日推荐