QT学习笔记(九)服务器与线程


头文件


#ifndef WIDGET_H
#define WIDGET_H
 
  
#include 
#include    // tcp 服务器类,=====> 负责监听是否有客户端连接
#include    // tcp socket  ======> 负责tcp的通信
 
  
namespace Ui {
class Widget;
}
 
  
class Widget : public QWidget
{
    Q_OBJECT
 
  
public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
 
  
public slots:
    void newClient();
 
  
    void readData();
 
  
private:
    Ui::Widget *ui;
 
  
    QTcpServer server;   //  定义一个服务器对象
};
 
  
#endif // WIDGET_H

服务器

#include "widget.h"
#include "ui_widget.h"
#include 
Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
 
  
    // 监听本地的 ip 和端口
    server.listen(QHostAddress::Any, 9999);
 
  
    connect(&server, SIGNAL(newConnection()), this, SLOT(newClient()));
}
 
  
Widget::~Widget()
{
    delete ui;
}
 
  
void Widget::newClient()
{
    // 一次性接收所有客户端的请求
    while(server.hasPendingConnections())    //有请求返回True,否则false
    {
        QTcpSocket *s = server.nextPendingConnection();
 
  
        QHostAddress addr = s->peerAddress();
        qint16 port       = s->peerPort();
 
  
        QString str = QString("有客户端连接,ip = %1  port = %2").arg(addr.toString()).arg(port);
        ui->textEdit->append(str);
 
  
 
  
        connect(s, SIGNAL(readyRead()), this, SLOT(readData()));
    }
}
void Widget::readData()
{
    // 要发送信息的客户端的socket
    QTcpSocket *s = (QTcpSocket *)sender();
 
  
    while (s->bytesAvailable())
    {
        QByteArray data = s->readAll();
        ui->textEdit->append(QString(data));
 
  
        s->write(data);
    }
}


Qt网络编程比较常用的两个类:QTcpServer和QTcpSocket。当然还有UDP的类(在这就不介绍了)。

这两个类的操作比较简单。


QTcpServer的基本操作:

1、调用listen监听端口。

2、连接信号newConnection,在槽函数里调用nextPendingConnection获取连接进来的socket。


QTcpSocket的基本能操作:

1、调用connectToHost连接服务器。

2、调用waitForConnected判断是否连接成功。

3、连接信号readyRead槽函数,异步读取数据。

4、调用waitForReadyRead,阻塞读取数据。


1、创建线程的一种方式是:
     1)、继承Thread
     2)、覆写run方法,将线程要运行的任务代码存储到run方法中
     3)、创建Thread类的子类对象。
     4)、调用start方法开启线程并调用run方法。

2、覆写父类中的方法,必须保证子类的方法与父类的方法一模一样。返回值类型,方法名,参数类型和个数都要跟父类的方法一致,才能进行覆盖

本题中,MyThread继承了Thread,但是没有覆写Thread中的run()方法,而使用start(),开启线程后,会执行run()方法中的内容,因为没有覆盖run(),所以线程开启后没有进行任何的操作就结束了。


 
  
 
  
 
  
 
 

你可能感兴趣的:(QT)