TCP(Transmission Control Protocol,传输控制协议)
TCP 是一个用于数据传输的地城网络协议,多个网络协议包括(HTTP 和 FTP 都是基于TCP 协议),TCP 是面向数据流和连接的可靠的传输协议。
QTcpSocket 继 承 自 QAbstractSocket, 与 QUdpSocket 传 输 的数 据 报 不同 的 是 ,QTcpSocket 传输的是连续的数据流,尤其适合连续的数据传输,TCP 一般分为客户端和服务端,即 C/S (Client/Server 模型)。
QTcpSocket 代表了两个独立的数据流,一个用来读取数据,一个用来写入数据,分别采 用 QTcpSocket::read() 及 QTcpSocket::write() 操 作 , 读 取 数 据 前 先 调 用QTcpSocket::bytesAvailable 来确定已有足够的数据可用。
QTcpServer 处理客户端的连接,可通过 QTcpServer::listen()监听客户端发来的连接请求,每当有客户端连接时会发射 newConnection()信号,QTcpSocket 可用于读取客户端发来的数据报,亦可发送数据报
1>客户端
Widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include<QTcpSocket>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private slots:
void onReadMessage();
void onDisplayError(QAbstractSocket::SocketError);
void on_connectBtn_clicked();
void on_sendBtn_clicked();
private:
Ui::Widget *ui;
QTcpSocket* m_tcpSocket;
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
const int gTcpPort = 8888;
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
m_tcpSocket = new QTcpSocket(this);
//socket有数据来了,做处理
connect(m_tcpSocket,&QTcpSocket::readyRead,
this,&Widget::onReadMessage);
connect(m_tcpSocket,SIGNAL(QAbstractSocket::SocketError),
this,SLOT(onDisplayError(QAbstractSocket::SocketError)));
ui->hostLineEdit->setText("127.0.0.1");
ui->portLineEdit->setText(QString::number(gTcpPort));
}
Widget::~Widget()
{
delete ui;
}
void Widget::onReadMessage()
{
QByteArray bt;
bt.resize(m_tcpSocket->bytesAvailable());
m_tcpSocket->read(bt.data(),bt.size());
ui->massgesLabbel->setText(bt);
}
void Widget::onDisplayError(QAbstractSocket::SocketError e)
{
qDebug() << "SocketError" << e << endl
<< m_tcpSocket->errorString();
}
void Widget::on_connectBtn_clicked()
{
m_tcpSocket->abort();
//IP 端口
m_tcpSocket->connectToHost(ui->hostLineEdit->text(),
ui->portLineEdit->text().toInt());
}
void Widget::on_sendBtn_clicked()
{
m_tcpSocket->write(ui->sendLineEdit->text().toUtf8());
m_tcpSocket->flush();
}
2>服务端
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include<QTcpServer>
#include<QtcpSocket>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private slots:
void onNewConnect();//客户端新的连接请求处理
void onSendMessage();//反馈信息给客户端新的连接
void onReadMessage();//读取数据
private:
Ui::Widget *ui;
QTcpServer *m_tcpSever;
QTcpSocket *m_tcpSocket;
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
m_tcpSever = new QTcpServer(this);
//监听客户端发来的请求
if(!m_tcpSever->listen(QHostAddress::Any,8888)){
qDebug() << m_tcpSever->errorString();
close();
}
connect(m_tcpSever,&QTcpServer::newConnection,
this,&Widget::onNewConnect);
connect(m_tcpSever,&QTcpServer::newConnection,
this,&Widget::onSendMessage);
}
Widget::~Widget()
{
delete ui;
}
void Widget::onNewConnect()
{
//当前连接的客户端
m_tcpSocket = m_tcpSever->nextPendingConnection();
//断开连接
connect(m_tcpSocket,&QTcpSocket::disconnected,
m_tcpSocket,&QTcpSocket::deleteLater);
//soctet有数据时会发送readyRead信号
connect(m_tcpSocket,&QTcpSocket::readyRead,
this,&Widget::onReadMessage);
}
void Widget::onSendMessage()
{
QString str = "你好!客户端";
m_tcpSocket->write(str.toUtf8());
ui->label->setText("发送数据成功");
}
void Widget::onReadMessage()
{
QByteArray bt =m_tcpSocket->readAll();
ui->readLabel->setText(bt);
}