用QT写一个TCP通信助手(三、TCP通信)

16 篇文章 9 订阅
14 篇文章 1 订阅

一、说明

首先我们先分析一下:
由于不支持多继承,所以比MFC稍微麻烦了一点,但是QT又具有它自身的优势,那就是信号和槽,我们不用开线程去监听一些事件的触发,会方便许多。

二、 创建一个TCP类

这个类的作用是将客户端和服务端的代码进行一定程度上的统一,便于界面去交互调用。
首先有五个基本方法:

  1. 连接/启动
  2. 断开连接
  3. 是否已经连接
  4. 发送
  5. 接收
    其次呢,有一个发射的信号和槽,这是为了监听连接状态
    最后还有一个Getsocket的方法,这个主要是用来获取socket状态使用

.h文件

#ifndef QTCP_H
#define QTCP_H

#include <QObject>
#include <QTcpSocket>
#include "TcpClient.h"
#include "TcpServer.h"

enum ConnMode{
    CLIENT_MODE,
    SERVER_MODE
};

class QTCP : public QObject
{
    Q_OBJECT
public:
    explicit QTCP(QObject *parent = nullptr);

signals:
    void Connected();
private slots:
    void ConnOK();
public:
    QTcpSocket* GetSocket();
public:
    bool SetMode(ConnMode mode);
    bool Connect(QString ip ,int port);
    bool IsConnect();
    bool DisConn();
    bool Send(QString data);
    bool recv(QString &data);
protected:
    bool m_IsConnect;
    ConnMode m_mode;
    TcpServer *m_server;
    TcpClient *m_client;
    QTcpSocket *m_socket;
};

#endif // QTCP_H

.cpp文件

#include "qtcp.h"
QTCP::QTCP(QObject *parent) : QObject(parent)
{
    m_server = new TcpServer(parent);
    m_client = new TcpClient(parent);
    connect(m_client, &TcpClient::Connected, this, &QTCP::ConnOK);
    connect(m_server, &TcpServer::Connected, this, &QTCP::ConnOK);
}

void QTCP::ConnOK()
{
    emit Connected();
}

QTcpSocket *QTCP::GetSocket()
{

    switch(m_mode){
    case CLIENT_MODE:
        m_socket = m_client->GetSocket();

        break;
    case SERVER_MODE:
        m_socket = m_server->GetSocket();

        break;
    }

    return m_socket;
}

bool QTCP::SetMode(ConnMode mode)
{
    m_mode = mode;
    DisConn();
}

bool QTCP::Connect(QString ip, int port)
{
    bool ret = false;
    switch(m_mode){
    case CLIENT_MODE:
        ret = m_client->Connect(ip,port);
        break;
    case SERVER_MODE:
        ret = m_server->Connect(ip,port);

        break;
    }
    return ret;
}

bool QTCP::IsConnect()
{
    bool ret = false;
    switch(m_mode){
    case CLIENT_MODE:
        ret = m_client->IsConnect();
        break;
    case SERVER_MODE:
        ret = m_server->IsConnect();
        break;
    }
    return ret;
}

bool QTCP::DisConn()
{
    if(!IsConnect()){
        qWarning()<<"未连接";
        return false;
    }
    bool ret = false;
    switch(m_mode){
    case CLIENT_MODE:
        ret = m_client->DisConn();
        break;
    case SERVER_MODE:
        ret = m_server->DisConn();
        m_server->SetDisConn();
        break;
    }
    return ret;
}

bool QTCP::Send(QString data)
{
    if(!IsConnect()){
        qWarning()<<"未连接";
        return false;
    }
    bool ret = false;
    switch(m_mode){
    case CLIENT_MODE:
        ret = m_client->Send(data);
        qInfo()<<"客户端发送数据:"<<data;
        break;
    case SERVER_MODE:
        ret = m_server->Send(data);
        qInfo()<<"服务端发送数据:"<<data;
        break;
    }

    return ret;
}

bool QTCP::recv(QString &data)
{
    if(!IsConnect()){
        qWarning()<<"未连接";
        return false;
    }
    bool ret = false;
    switch(m_mode){
    case CLIENT_MODE:
        ret = m_client->recv(data);
        qInfo()<<"客户端接收数据:"<<data;
        break;
    case SERVER_MODE:
        ret = m_server->recv(data);
        qInfo()<<"服务端接收数据:"<<data;
        break;
    }
    return ret;
}

三、客户端

创建一个客户端实现上述所有的方法
.h文件

#pragma once

#include <QObject>
#include <QTcpSocket>
class TcpClient : public QObject
{
    Q_OBJECT
public:
    TcpClient(QObject *parent = nullptr);
	~TcpClient();

signals:
    void Connected();
public:
	bool Connect(QString ip, int port);
	bool IsConnect();
	bool Send(QString data);
	bool recv(QString& data);
	bool DisConn();
    QTcpSocket* GetSocket();
private:
    QTcpSocket* m_socket;
    bool m_IsConnect;
};

.cpp文件

#include "TcpClient.h"

TcpClient::TcpClient(QObject *parent):QObject(parent)
{
    m_socket = new QTcpSocket();
    m_IsConnect = false;
}

TcpClient::~TcpClient()
{
}

bool TcpClient::Connect(QString ip, int port)
{
	m_socket->connectToHost(ip,port);
    emit Connected();
	return true;
}

bool TcpClient::IsConnect()
{
	return m_socket->isValid();
}

bool TcpClient::Send(QString data)
{
	return m_socket->write(data.toLocal8Bit());
}

bool TcpClient::recv(QString& data)
{
	data = QString::fromLocal8Bit(m_socket->readAll());
	return true;
}

bool TcpClient::DisConn()
{
	m_socket->close();
	return true;
}

QTcpSocket* TcpClient::GetSocket()
{
	return m_socket;
}

四、服务端

.h文件

#pragma once

#include <QTcpServer>
#include <QTcpSocket>
class TcpServer : public QObject
{
    Q_OBJECT
public:
    TcpServer(QObject *parent = nullptr);
	~TcpServer();
signals:
    void Connected();

public:
	bool Connect(QString ip, int port);
	bool IsConnect();
	bool Send(QString data);
	bool recv(QString& data);
	bool DisConn();
	QTcpSocket* GetSocket();

public slots:
	void SetConn();
	void SetDisConn();
private:
	QTcpServer m_Server;
    QTcpSocket* m_socket;
    bool m_IsConnect;
};

.cpp文件

#include "TcpServer.h"

TcpServer::TcpServer(QObject *parent):QObject(parent)
{
    m_IsConnect = false;
    m_socket = new QTcpSocket();
}

TcpServer::~TcpServer()
{
}

bool TcpServer::Connect(QString ip, int port)
{
	if (!m_Server.listen(QHostAddress::AnyIPv4, port)) {
		return false;
	}
    qInfo()<<"服务器启动成功";
	QObject::connect(&m_Server, &QTcpServer::newConnection, this, &TcpServer::SetConn);
	return true;

}

bool TcpServer::IsConnect()
{
	return m_IsConnect;
}

bool TcpServer::Send(QString data)
{
	return m_socket->write(data.toLocal8Bit());
}

bool TcpServer::recv(QString& data)

{
	QByteArray b = m_socket->readAll();
	data = QString ::fromLocal8Bit(b);
	if (data.isEmpty()) {
		return false;
	}
	return true;
}

bool TcpServer::DisConn()
{
	m_Server.close();
    m_socket->close();
    m_socket->disconnectFromHost();
	return true;
}

QTcpSocket* TcpServer::GetSocket()
{
	return m_socket;
}

void TcpServer::SetConn()
{
	if (!m_IsConnect && m_Server.hasPendingConnections()) {
		m_socket = m_Server.nextPendingConnection();
		emit Connected();
	}
	m_IsConnect = true;
}

void TcpServer::SetDisConn()
{
	m_IsConnect = false;
}

五、说明

pro文件中需要加入network
在这里插入图片描述
下一篇:用QT写一个TCP通信助手(四、界面交互)

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值