QT的网络编程有TCP和UDP,本篇文章先讲一下TCP。
TCP编程需要用到两个类,QTcpServer和QTcpSocket,客户端只需要用到后者,服务器两个类都会用到。我们来试一下完成一个服务器和一个客户端
一、服务器制作
1.添加库和头文件
在帮助里面搜QTcpServer和QTcpSocket,可以看到我们需要添加network,和头文件QTcpServer。
新建一个工程,在pro文件修改此行代码
QT += core gui network
//network为新加字段
在widget.h文件中添加头文件
#include <QTcpServer>
#include <QTcpSocket>
添加完记得编译一下,没问题就进行下一步。
2.实例化
在widget.h文件中命名
class Widget : public QWidget
{
Q_OBJECT
public:
...
QTcpServer *tcpServer;
QTcpSocket *tcpSocket;
};
在widget.cpp中new一个实例
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
...
tcpServer=new QTcpServer(this);
tcpSocket=new QTcpSocket(this);
}
3.布局
因为接收窗口只用来显示收到的数据,所以将其在属性栏首选readOnly。为了方便编程,我们给框改名字。
4.编码
关于三个按键的槽函数,直接在ui界面转到槽进行编写即可。
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
tcpServer=new QTcpServer(this);
tcpSocket=new QTcpSocket(this);
connect(tcpServer,SIGNAL(newConnection()),this,SLOT(newConnection_Slot()));
}
void Widget::newConnection_Slot()
{
tcpSocket=tcpServer->nextPendingConnection();
connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(readyRead_Slot()));
}
void Widget::readyRead_Slot()
{
QString buf;
buf=tcpSocket->readAll();
ui->recvEdit->appendPlainText(buf);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_openBt_clicked()
{
//QHostAddress::Any监听来自所有人的链接,端口号(转成无符号类型)
tcpServer->listen(QHostAddress::Any,ui->portEdit->text().toUInt());//开始监听
}
void Widget::on_closeBt_clicked()
{
tcpServer->close();
}
void Widget::on_sendBt_clicked()
{
tcpSocket->write(ui->sendEdit->text().toLocal8Bit().data());
}
二、客户端制作
1.创建项目
在pro文件中加入network。
在头文件中把TcpSocket库包含进去。
2.布局
修改控件名
3.编码
widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
tcpSocket=new QTcpSocket(this);
}
//关联readyRead信号
void Widget::connected_Slot()
{
connect(tcpSocket,SIGNAL(readyRead()),this,SLOT(readyRead_Slot()));
}
//在此槽函数里面进行读操作
void Widget::readyRead_Slot()
{
ui->recvEdit->appendPlainText(tcpSocket->readAll());
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_openBt_clicked()
{
//链接服务器
tcpSocket->connectToHost(ui->IPEdit->text(),ui->portEdit->text().toUInt());
//链接成功之后会发送connect信号
connect(tcpSocket,SIGNAL(connected()),this,SLOT(connected_Slot()));
}
void Widget::on_closeBt_clicked()
{
tcpSocket->close();
}
void Widget::on_sendBt_clicked()
{
tcpSocket->write(ui->sendEdit->text().toLocal8Bit().data());
}
记得在widget.h文件中声明
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QTcpSocket>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
QTcpSocket *tcpSocket;
public:
explicit Widget(QWidget *parent = 0);
~Widget();
//声明槽函数
private slots:
void on_openBt_clicked();
void connected_Slot();
void readyRead_Slot();
void on_closeBt_clicked();
void on_sendBt_clicked();
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
三、验证
同时在打开服务器和客户端的QT工程,利用win+r,输入cmd,输入ipconfig查看电脑ip,然后填入客户端中,填写相同的端口号,然后打开服务器和客户端,就可以互相发送数据啦。
tips:
1.如果没有正常运行,查看一下是否已经补充了pro文件、是否在头文件包含了库、已经SLOT函数是不是写进去了是不是声明了。
2.多写几次就会知道,关闭按钮的槽函数很简单,直接close就行,conncet函数的槽函数SOLT()括号里总是得写槽函数的名字,并在头文件中声明,在cpp文件中编写槽函数的具体内容。
3.从Edit写内容时,需要用toLocal8bit().data()转化一下格式。