很多情形下,我们在应用程序的最外层都使用TCP作为可靠控制,下面,我就总结一下我在项目中使用QTcpServer与QTcpSocket的一些心得和体会。
服务端TCP程序可以利用QTcpServer,首先我们声名QTcpServer *对象(注意:QTcpServer占用的网络资源需要我们手动释放,任何我们程序可能异常退出或正常结束的地方QTcpServer *最后都要close())
注意我们的服务端要一直监听客户端
tcpPort=8888;
tcpServer=new QTcpServer();
if(!tcpServer->listen(QHostAddress::Any,tcpPort))
{
tcpServer->close();
emit MSG(QString("listen erro"));
}
connect(tcpServer,&QTcpServer::newConnection,this,&TcpServer::onNewConnection);
在新连接对应的槽里我们把
QTcpSocket *newpeer=tcpServer->nextPendingConnection();
这个新连接的socket指针取下来,进行操作,当执行newpeer->write(QByterArray &MSG)即服务器向此peer发送数据;当执行QByterArray MSG=newpeer->write()即服务器读此peer的数据,所有信息的传递均是对QTcpSocket的操作,并要要对每一个socket的disconnected连接deleteLater槽防止内存泄漏。
说到此处,就牵涉到了QString 与QByterArray的转换,因为我们平时处理消息大多是对QSring进行处理:
QString->QByterArray(只有英文(Latin)时):
newpeer->write(QString("Server").toLatin1());
QByterArray-> QString:
QTextCodec *tc= QTextCodec::codecForName("UTF-8");
QString str=tc->toUnicode((QByteArray)
rawreply)
下面的代码抽取自 我的服务端程序
#ifndef TCPSERVER_H
#define TCPSERVER_H
#include <QObject>
#include<QTcpServer>
#include<QAbstractSocket>
class TcpServer : public QObject
{
Q_OBJECT
public:
explicit TcpServer(QObject *parent = 0);
~TcpServer();
private:
int nb_peer;//总共的小伙伴数目,用于确定client->index的取值
QTcpServer *tcpServer;
public slots:
void ReadDataFromSocket();
void onNewConnection();
void onDisConnection();
void processMSG(QString &MSG);
// void processAddedClient(QTcpSocket *client);
};
#include "tcpserver.h"
TcpServer::TcpServer(QObject *parent) :
QObject(parent),nb_peer(0)
{
tcpPort=8888;
tcpServer=new QTcpServer();
if(!tcpServer->listen(QHostAddress::Any,tcpPort))
{
tcpServer->close();
emit MSG(QString("listen erro"));
}
peerList = QList<client>();
connect(tcpServer,&QTcpServer::newConnection,this,&TcpServer::onNewConnection);
}
void TcpServer::onNewConnection()
{
QTcpSocket *newpeer=tcpServer->nextPendingConnection();
//写入验证
connect(newpeer,SIGNAL(readyRead()),this,SLOT(ReadDataFromSocket()));
connect(newpeer,SIGNAL(disconnected()),newpeer,SLOT(deleteLater()));
connect(newpeer,SIGNAL(disconnected()),this,SLOT(onDisConnection()));
newpeer->write(QString("Server").toLatin1());
newpeer->flush();
}
#include<QTextCodec>
#include<iterator>
void TcpServer::ReadDataFromSocket()
{
QByteArray rawreply= static_cast<QTcpSocket*>(sender())->readAll();
QTextCodec *tc= QTextCodec::codecForName("UTF-8");
client beingCheckedClient;
beingCheckedClient.index=nb_peer;
beingCheckedClient.socket=static_cast<QTcpSocket*>(sender());
if(tc->toUnicode(rawreply)!=QString("Client")&& !peerList.contains(beingCheckedClient
))
{
//写入信息
//emit ChangeLabel(QString(rawreply));
static_cast<QTcpSocket*>(sender())->write(
QString("connect time out! disconnecting...").toLatin1());
static_cast<QTcpSocket*>(sender())->flush();
static_cast<QTcpSocket*>(sender())->disconnectFromHost();
return ;
}
}
TcpServer::~TcpServer()
{
tcpServer->close();
}