这段时间用到了QT的TCP通信,做了初步的学习与尝试,编写了一个客户端和服务器基于窗口通信的小例程。使用QT的网络套接字需要.pro文件中加入一句:QT+=network一、客户端1、客户端的代码...

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

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

QT += network

一、客户端

(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();

首先是mainwindow.h文件:

//mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTcpSocket>

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 QT编程学习网cpSocket();

  //连接信号槽
  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();

首先是mainwindow.h文件:

//mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTcpServer>
#include <QTcpSocket>

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()<<server->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的设计:

三、运行结果

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。