1.TCP
服务器端: 监听套接字 QTcpServer; 通信套接字 QTcpSocket;
QTcpServer:
设置监听: listen(address, port)//addr客户端连接的ip,port接收数据的端口。
关闭监听: close()
监听到连接,发送信号: void newConnection()
保存连接到服务器的套接字: QTcpSocket* QTcpServer::nextPendingConnection().
QTcpSocket:
QTcpServer *conn;
客户端: 通信的套接字 QTcpSocket
连接到服务器: connectToHost(sserverIp, sserverPort)
与服务器断开连接: disconnectFromHost()
连接成功 发送信号: void connected(),连接到服务器。
服务器断开连接, 发出信号: void disconnected() 与上面信号对应。
收到数据 发出信号: void readyRead() 感知发送数据过来了。
发送数据: write
接收数据: read
2.UDP
面向无链接的,不安全。cs端的关系是对等的。
发数据: 带上对方的ip+port。
qint64 writeDatagram(const char* data, qint64 size,QHostAddress &addr, quint16 port)
qint64 writeDatagram(const QByteArray &datagram,QHostAddress &addr, quint16 port)
收数据:发过来的数据,
qint64 readDatagram(char* data, qint64 maxSize,QHostAddress *addr=0,quint16 *port=0);
要接收数据,需要绑定本地端口: bind(本地端口)
获取要接收的数据报文的大小:
qint64 pendingDatagramSize()
缓冲区建议使用 QByteArray
qint64 size = pendingDatagramSize()
QByteArray array(size, 0); //size个字节,初始化全部为0
readDatagram(array.data(), size);
有数据到达,触发信号: void readyRead()
多线程。
要掌握Qt 4.7+的使用方法。
在子线程中绘图。
注意事项:子线程不能操作UI
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include "myimage.h"
#include <QThread>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
void slotUpdate(QImage img);
protected:
void paintEvent(QPaintEvent *);
private:
Ui::Widget *ui;
QThread* pthred;
MyImage* pImage;
QImage image; //绘制的图片
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QPainter>
#include <QDebug>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
pImage = new MyImage; //业务类对象
pthred = new QThread(this); //子线程对象
pImage->moveToThread(pthred); //业务类移入子线程
pthred->start(); //子线程中启动子线程
//去执行绘制逻辑
connect(ui->pushButton, &QPushButton::clicked, pImage, &MyImage::DrawMyImage);
//监听回传信号sigImageDone,执行槽函数slotUpdate
connect(pImage, &MyImage::sigImageDone, this, &Widget::slotUpdate);
connect(this, &Widget::destroyed, this, [=]()
{
pthred->quit();
pthred->wait(); //线程等待
delete pImage;
});
qDebug() << QThread::currentThread() << "main";
}
void Widget::slotUpdate(QImage img)
{
image = img;//更新image
update();
}
void Widget::paintEvent(QPaintEvent *)
{
QPainter p(this);
p.drawImage(50, 50, image); //更新ui
}
Widget::~Widget()
{
delete ui;
//delete pImage;
}
myimage.h
#ifndef MYIMAGE_H
#define MYIMAGE_H
#include <QObject>
#include <QImage>
class MyImage : public QObject
{
Q_OBJECT
public:
explicit MyImage(QObject *parent = 0);
void DrawMyImage(); //画图,业务函数,在子线程中执行。
signals:
void sigImageDone(QImage img);//画图完成,将图片传出去
public slots:
};
#endif // MYIMAGE_H
myimage.cpp
#include "myimage.h"
#include <QPainter>
#include <QDebug>
#include <QThread>
MyImage::MyImage(QObject *parent) : QObject(parent)
{
}
void MyImage::DrawMyImage() //子线程中执行。
{
QImage image(600, 600, QImage::Format_ARGB32);
QPainter p(&image); // 指定绘图设备
QPoint points[6] =
{
QPoint(qrand()%500, qrand()%500),
QPoint(qrand()%500, qrand()%500),
QPoint(qrand()%500, qrand()%500),
QPoint(qrand()%500, qrand()%500),
QPoint(qrand()%500, qrand()%500),
QPoint(qrand()%500, qrand()%500)
};
p.setPen(QPen(Qt::green, 10));
p.setBrush(Qt::blue);
p.drawPolygon(points, 6); // 绘制多边形。
//image.save("d:\\myimage.png");//保存到本地
emit sigImageDone(image); //图片传出去。
qDebug() << QThread::currentThread();
}
main.cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}