1. 软件架构
- C/S架构
- B/S架构
- B/S是一种特殊的C/S架构
- B/S中的客服端统一使用浏览器Browser
- B/S中的客服端UI通常采用HTML进行开发
- B/S中的客服端和服务端通信通常采用http协议进行通信
2. TCP服务端编程
- Qt提供了QTcpServer类
- 将QTcpServer的对象当作黑盒使用,进行监听
- 每个连接生成一个QTcpSocket对象进行通信
QTcpServer的使用方式
- 监听本机地址的端口—listen()
- 通过信号通知客户端连接—newConnetion()
- 获取QTcpServer通信对象—nextPendingConnection()
- 停止监听—close()
- QTcpServer注意事项:
- 用于处理客户端连接,不进行具体通信
- 监听的端口只用于响应连接请求
- 监听到连接后,生成QTcpServer对象与客户端进行通信
3. 编程
serverdemo.h
#ifndef SERVERDEMO_H
#define SERVERDEMO_H
#include <QObject>
#include <QTcpServer>
class ServerDemo : public QObject
{
Q_OBJECT
QTcpServer m_server;
public:
explicit ServerDemo(QObject *parent = nullptr);
bool start(int port);
void stop();
~ServerDemo();
protected slots:
void onNewConnection();
void onConneted();
void onDisConneted();
void onDataRady();
void onBytesWritten(qint64 bytes);
};
#endif // SERVERDEMO_H
serverdemo.c
#include "serverdemo.h"
#include <QHostAddress>
#include <QTcpSocket>
#include <QObjectList>
#include <QDebug>
ServerDemo::ServerDemo(QObject *parent) : QObject(parent)
{
connect(&m_server,SIGNAL(newConnection()),this,SLOT(onNewConnection()));
}
void ServerDemo::onNewConnection()
{
qDebug()<<"onNewConnection";
QTcpSocket* tcp=m_server.nextPendingConnection();
connect(tcp,SIGNAL(connected()),this,SLOT(onConneted()));
connect(tcp,SIGNAL(disconnected()),this,SLOT(onDisConneted()));
connect(tcp,SIGNAL(readyRead()),this,SLOT(onDataRady()));
connect(tcp,SIGNAL(bytesWritten(qint64)),this,SLOT(onBytesWritten(qint64)));
}
void ServerDemo::onConneted()
{
QTcpSocket* tcp=dynamic_cast<QTcpSocket*>(sender());
if(tcp!=NULL)
{
qDebug()<<"onConneted()";
qDebug()<<"Local Address"<<tcp->localAddress();
qDebug()<<"Local Port"<<tcp->localPort();
}
}
void ServerDemo::onDisConneted()
{
qDebug()<<"onDisconneted()";
}
void ServerDemo::onDataRady()
{
QTcpSocket* tcp=dynamic_cast<QTcpSocket*>(sender());
char buf[256]={0};
if(tcp!=NULL)
{
qDebug()<<"onDataRady()"<<tcp->read(buf,sizeof(buf)-1);
qDebug()<<"Data:"<<buf;
}
}
void ServerDemo::onBytesWritten(qint64 bytes)
{
qDebug()<<"onBytesWritten()"<<bytes;
}
bool ServerDemo::start(int port)
{
bool ret = true;
if(!m_server.isListening())
{
return m_server.listen(QHostAddress("127.0.0.1"),port);
}
return ret;
}
void ServerDemo::stop()
{
if(m_server.isListening())
{
m_server.close();
}
}
ServerDemo::~ServerDemo()
{
const QObjectList& list=m_server.children();
for(int i=0;i<list.length();i++)
{
QTcpSocket*tcp= dynamic_cast<QTcpSocket*>(list[i]);
if(tcp != NULL)
{
tcp->close();
}
}
}
main.c
int main(int argc, char *argv[])
{
/* char data[]="hello world!!!";
QCoreApplication a(argc, argv);
ClientDemo client;
client.connectTo("127.0.0.1",8000);
client.send(data,sizeof(data)-1);
return a.exec();*/
QCoreApplication a(argc, argv);
ServerDemo server;
server.start(8080);
return a.exec();
}