头文件
#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(),所以线程开启后没有进行任何的操作就结束了。