欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

使用QTcpServer创建一个简单的服务器程序之一:单线程服务器

程序员文章站 2022-03-15 10:14:39
...

Qt提供了QTcpServer和QTcpSocket两个类用来创建服务器相关程序,其中QTcpServer就是一个监听使用的socket,并不负责与客户端通信。QTcpSocket就是负责与客户端通信的socket。

既然要创建一个简单的服务器程序,那么我就不从QTcpServer和QTcpSocket继承出新的类来实现了,毕竟用组合的方式来实现更为简单。

这个思路很简单,我就一边说思路一边写一些简单的代码。

1,在主程序中,包含QTcpServer和QTcpSocket两个类的对象,作为自己的成员变量使用。

QTcpServer *m_listenSocket;//监听socket
QTcpSocket *m_clientSocket;//同客户端通信的socket

//既然是服务器,就可能会有多个客户端来连接,所以这里要存所有客户端
//我只在本机进行测试,所以IP地址都相同,这里用端口号来区别不同的客户端
QMap<quint16, QTcpSocket *> m_map;//key为端口号

2,开始监听,并且连接新客户端加入的信号。新客户端加入之后,就可以连接一些常用的信号了

//注:我测试程序的类是MyNetWork,就是一个基于QWidget的窗口程序
//点击开始按钮,打开服务器
void MyNetWork::on_pB_start_clicked()
{
  if(m_listenSocket->listen(QHostAddress::AnyIPv4,6000))
        ui->textEdit->append("开启服务器成功");

  connect(m_listenSocket,&QTcpServer::newConnection,this,&MyNetWork::SlotNewConnect);
}

//新客户端加入的槽函数
void MyNetWork::SlotNewConnect()
{
     m_clientSocket = new QTcpSocket();
     m_clientSocket = m_listenSocket->nextPendingConnection();//这里才能得到与客户端通信的socket

     connect(m_clientSocket,&QTcpSocket::readyRead,this,&MyNetWork::SlotReadMessage);
     connect(m_clientSocket,&QTcpSocket::disconnected,this,&MyNetWork::SlotDisConnect);
  
//这里是真正的删除操作
connect(m_clientSocket,&QTcpSocket::disconnected,m_clientSocket,&QTcpSocket::deleteLater);

     m_map.insert(m_clientSocket->peerPort(),m_client);
     ui->textEdit->append(QString("客户端[%1]连接").arg(m_clientSocket->peerPort()));
}

3,读信号和断开连接信号处理

void MyNetWork::SlotReadMessage()
{
    QByteArray buf;
    buf = m_clientSocket->readAll();
    ui->textEdit->append(QString("客户端%1").arg(m_clientSocket->peerPort())+QString(buf));
}

void MyNetWork::SlotDisConnect()
{
    ui->textEdit->append("客户端断开连接");
}

4,发送信息(这里只实现了对所有客户端的发送)

//点击发送按钮,发送数据
void MyNetWork::on_pB_send_clicked()
{
    QString str = ui->lineEdit->text();

    QMap<quint16, QTcpSocket *>::iterator it;
    for(it = m_map.begin();it != m_map.end();it++)
    {
        ((QTcpSocket *)it.value())->write(str.toLatin1());
    }
}

5,关闭服务器

void MyNetWork::on_pB_close_clicked()
{
    //不再监听新客户端加入了
    m_listenSocket->close();

    //断开已有的所有客户端
    QMap<quint16, QTcpSocket *>::iterator it;
    for(it = m_map.begin();it != m_map.end();it++)
    {
        ((QTcpSocket *)it.value())->disconnected();
    }
    
}

 

相关标签: Qt