这段时间用到了QT的TCP通信,做了初步的学习与尝试,编写了一个客户端和服务器基于窗口通信的小例程。

使用QT的网络套接字需要.pro文件中加入一句:

QT += network

一、客户端

1、客户端的代码比服务器稍简单,总的来说,使用QT中的QTcpSocket类与服务器进行通信只需要以下5步:

(1)创建QTcpSocket套接字对象

socket = new QTcpSocket();

(2)使用这个对象连接服务器

socket->connectToHost(IP, port);

(3)使用write函数向服务器发送数据

socket->write(data)

(4)当socket接收缓冲区有新数据到来时,会发出readRead()信号,因此为该信号添加槽函数以读取数据

QObject::connect(socket, &QTcpSocket::readyRead, this, &MainWindow::socket_Read_Data);

void MainWindow::socket_Read_Data()

{

QByteArray buffer;

//读取缓冲区数据

buffer = socket->readAll();

}

(5)断开与服务器的连接(关于close()和disconnectFromHost()的区别,可以按F1看帮助)

socket->disconnectFromHost();

2、以下是客户端的例程

首先是mainwindow.h文件:

//mainwindow.h

#ifndef MAINWINDOW_H

#define MAINWINDOW_H

#include

#include

namespace Ui {

class MainWindow;

}

class MainWindow : public QMainWindow

{

Q_OBJECT

public:

explicit MainWindow(QWidget *parent = 0);

~MainWindow();

private slots:

void on_pushButton_Connect_clicked();

void on_pushButton_Send_clicked();

void socket_Read_Data();

void socket_Disconnected();

private:

Ui::MainWindow *ui;

QTcpSocket *socket;

};

#endif // MAINWINDOW_H

然后是mainwindow.cpp文件:

//mainwindow.cpp

#include "mainwindow.h"

#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :

QMainWindow(parent),

ui(new Ui::MainWindow)

{

ui->setupUi(this);

socket = new QTcpSocket();

//连接信号槽

QObject::connect(socket, &QTcpSocket::readyRead, this, &MainWindow::socket_Read_Data);

QObject::connect(socket, &QTcpSocket::disconnected, this, &MainWindow::socket_Disconnected);

ui->pushButton_Send->setEnabled(false);

ui->lineEdit_IP->setText("127.0.0.1");

ui->lineEdit_Port->setText("8765");

}

MainWindow::~MainWindow()

{

delete this->socket;

delete ui;

}

void MainWindow::on_pushButton_Connect_clicked()

{

if(ui->pushButton_Connect->text() == tr("连接"))

{

QString IP;

int port;

//获取IP地址

IP = ui->lineEdit_IP->text();

//获取端口号

port = ui->lineEdit_Port->text().toInt();

//取消已有的连接

socket->abort();

//连接服务器

socket->connectToHost(IP, port);

//等待连接成功

if(!socket->waitForConnected(30000))

{

qDebug() << "Connection failed!";

return;

}

qDebug() << "Connect successfully!";

//发送按键使能

ui->pushButton_Send->setEnabled(true);

//修改按键文字

ui->pushButton_Connect->setText("断开连接");

}

else

{

//断开连接

socket->disconnectFromHost();

//修改按键文字

ui->pushButton_Connect->setText("连接");

ui->pushButton_Send->setEnabled(false);

}

}

void MainWindow::on_pushButton_Send_clicked()

{

qDebug() << "Send: " << ui->textEdit_Send->toPlainText();

//获取文本框内容并以ASCII码形式发送

socket->write(ui->textEdit_Send->toPlainText().toLatin1());

socket->flush();

}

void MainWindow::socket_Read_Data()

{

QByteArray buffer;

//读取缓冲区数据

buffer = socket->readAll();

if(!buffer.isEmpty())

{

QString str = ui->textEdit_Recv->toPlainText();

str+=tr(buffer);

//刷新显示

ui->textEdit_Recv->setText(str);

}

}

void MainWindow::socket_Disconnected()

{

//发送按键失能

ui->pushButton_Send->setEnabled(false);

//修改按键文字

ui->pushButton_Connect->setText("连接");

qDebug() << "Disconnected!";

}

最后是ui的设计:

 

二、服务器

1、服务器除了使用到了QTcpSocket类,还需要用到QTcpSever类。即便如此,也只是比客户端复杂一点点,用到了6个步骤:

(1)创建QTcpSever对象

server = new QTcpServer();

(2)侦听一个端口,使得客户端可以使用这个端口访问服务器

server->listen(QHostAddress::Any, port);

(3)当服务器被客户端访问时,会发出newConnection()信号,因此为该信号添加槽函数,并用一个QTcpSocket对象接受客户端访问

connect(server,&QTcpServer::newConnection,this,&MainWindow::server_New_Connect);

void MainWindow::server_New_Connect()

{

//获取客户端连接

socket = server->nextPendingConnection();

}

(4)使用socket的write函数向客户端发送数据

socket->write(data)

(5)当socket接收缓冲区有新数据到来时,会发出readRead()信号,因此为该信号添加槽函数以读取数据

QObject::connect(socket, &QTcpSocket::readyRead, this, &MainWindow::socket_Read_Data);

void MainWindow::socket_Read_Data()

{

QByteArray buffer;

//读取缓冲区数据

buffer = socket->readAll();

}

(6)取消侦听

server->close();

2、以下是服务器的例程

首先是mainwindow.h文件:

//mainwindow.h

#ifndef MAINWINDOW_H

#define MAINWINDOW_H

#include

#include

#include

namespace Ui {

class MainWindow;

}

class MainWindow : public QMainWindow

{

Q_OBJECT

public:

explicit MainWindow(QWidget *parent = 0);

~MainWindow();

private slots:

void on_pushButton_Listen_clicked();

void on_pushButton_Send_clicked();

void server_New_Connect();

void socket_Read_Data();

void socket_Disconnected();

private:

Ui::MainWindow *ui;

QTcpServer* server;

QTcpSocket* socket;

};

#endif // MAINWINDOW_H

然后是mainwindow.cpp文件:

#include "mainwindow.h"

#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :

QMainWindow(parent),

ui(new Ui::MainWindow)

{

ui->setupUi(this);

ui->lineEdit_Port->setText("8765");

ui->pushButton_Send->setEnabled(false);

server = new QTcpServer();

//连接信号槽

connect(server,&QTcpServer::newConnection,this,&MainWindow::server_New_Connect);

}

MainWindow::~MainWindow()

{

server->close();

server->deleteLater();

delete ui;

}

void MainWindow::on_pushButton_Listen_clicked()

{

if(ui->pushButton_Listen->text() == tr("侦听"))

{

//从输入框获取端口号

int port = ui->lineEdit_Port->text().toInt();

//监听指定的端口

if(!server->listen(QHostAddress::Any, port))

{

//若出错,则输出错误信息

qDebug()<errorString();

return;

}

//修改按键文字

ui->pushButton_Listen->setText("取消侦听");

qDebug()<< "Listen succeessfully!";

}

else

{

/*

//如果正在连接(点击侦听后立即取消侦听,若socket没有指定对象会有异常,应修正——2017.9.30)

if(socket->state() == QAbstractSocket::ConnectedState)

{

//关闭连接

socket->disconnectFromHost();

}

*/

socket->abort();

//取消侦听

server->close();

//修改按键文字

ui->pushButton_Listen->setText("侦听");

//发送按键失能

ui->pushButton_Send->setEnabled(false);

}

}

void MainWindow::on_pushButton_Send_clicked()

{

qDebug() << "Send: " << ui->textEdit_Send->toPlainText();

//获取文本框内容并以ASCII码形式发送

socket->write(ui->textEdit_Send->toPlainText().toLatin1());

socket->flush();

}

void MainWindow::server_New_Connect()

{

//获取客户端连接

socket = server->nextPendingConnection();

//连接QTcpSocket的信号槽,以读取新数据

QObject::connect(socket, &QTcpSocket::readyRead, this, &MainWindow::socket_Read_Data);

QObject::connect(socket, &QTcpSocket::disconnected, this, &MainWindow::socket_Disconnected);

//发送按键使能

ui->pushButton_Send->setEnabled(true);

qDebug() << "A Client connect!";

}

void MainWindow::socket_Read_Data()

{

QByteArray buffer;

//读取缓冲区数据

buffer = socket->readAll();

if(!buffer.isEmpty())

{

QString str = ui->textEdit_Recv->toPlainText();

str+=tr(buffer);

//刷新显示

ui->textEdit_Recv->setText(str);

}

}

void MainWindow::socket_Disconnected()

{

//发送按键失能

ui->pushButton_Send->setEnabled(false);

qDebug() << "Disconnected!";

}

最后是ui的设计:

 

三、运行结果

  进群领取qt开发学习资料以及技术交流  在下方↓↓↓↓↓↓↓↓

好文推荐

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: