QT实现TCP通信的小问题

QT实现TCP通信程序虚心请教

本人大四做毕设时需要QT实现TCP通信,目前程序通过相关参考已经编好,在自己PC上打开两个进程也可以实现相应功能;但是当将该程序用两个PC(这两个PC已接入局域网)分别运行时,一个作为服务器、一个作为客户端运行时,不可以正常连接,运行客户端的PC连接不到服务器的进程上。

已做尝试

  1. 两台PC分别可以Ping到对方;
  2. 尝试将两台PC的防火墙均关闭;
  3. 两台PC的IP为XXX.XXX.XXX.30/XXX.XXX.XXX.31;
  4. netsh allow端口也尝试过;

虚心请教

本人小白一枚,尝试过以上四种方法均不可以,虚心求教:

  1. 如何实现两台在同一局域网的PC的TCP通信;
  2. 如何利用QT实现广域网的两台PC的TCP通信;
    源代码附上~谢谢各位大佬
    QT .h文件
#ifndef MYTCP_H
#define MYTCP_H
#include <QMainWindow>
#include <QTcpServer>
#include <QTcpSocket>
#include <QHostAddress>
#include <QFile>
#include <QTimer>
#include <QMessageBox>
#include <QVector>
namespace Ui {
class mytcp;
}

class mytcp : public QMainWindow
{
    Q_OBJECT

public:
    explicit mytcp(QWidget *parent = nullptr);
    ~mytcp();

private:
    Ui::mytcp *ui;

private slots:
void on_severRB_clicked();//选择作为服务器

void on_clientRB_clicked();//选择作为客户端
void on_StartBt_clicked();//启动服务器或链接客户端
void on_closeBt_clicked();//关闭服务器或断开客户端
void on_onlineUserList_doubleClicked(const QModelIndex &index);//选择给哪个客户端发送数据
void on_autoCB_clicked(bool checked);//选择自动发送还是手动发送
void on_sendMsgBt_clicked();//发送信息
void ReadError(QAbstractSocket::SocketError);


//服务器
void accept_connect();//与newconnection信号关联
void recv_data(); //接收数据

void auto_time_send();//定时器定时发送数据
void client_disconnect();//关联掉线信号
void connect_suc();//检测客户端连接成功信号
void on_clearRcvBt_clicked();
void on_clearSendBt_clicked();

private:

         QTimer *mTimer;//定时发送数据
         QTcpServer *mServer;
         QTcpSocket *mSocket;
         QVector<QTcpSocket*> clients; //存储所有在线客户端(容器)

         bool isServer;//标志位,true为服务器,false为客户端

         //保存接收和发送数据的字节数
         qint64 recvSize;
         qint64 sendSize;
         qint16 onNum;
      bool isCheckServer;//判断是否选择了服务器
      bool isCheckClient;//判断是否选择了客户端
};

#endif // MYTCP_H

QT .cpp文件

#include "mytcp.h"
#include "ui_mytcp.h"
#include <QPushButton>
#include <QDebug>

mytcp::mytcp(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::mytcp),
    onNum(0)
{
    ui->setupUi(this);
    this->setFixedSize(513,490);
    this->setWindowTitle("TCP数据通信");
    recvSize = 0;
    sendSize = 0;
    //初始化定时器
    mTimer = new QTimer();
    connect(mTimer,SIGNAL(timeout()),this,SLOT(auto_time_send()));

    //隐式connect 不需要在显式connect
    //connect(ui->radioClient, SIGNAL(toggled(bool)), this , SLOT(on_clientRB_clicked()));
    //connect(ui->radioServer, SIGNAL(toggled(bool)), this, SLOT(on_severRB_clicked()));

}

mytcp::~mytcp()
{
    delete ui;
}

//与newconnection信号关联
void mytcp::accept_connect()
{
     mSocket = mServer->nextPendingConnection(); //返回与客户端连接通信的套接字

     //关联接收数据信号
     connect(mSocket, SIGNAL(readyRead()),this,SLOT(recv_data()));
     //关联掉线信号
     connect(mSocket, SIGNAL(disconnected()),this,SLOT(client_disconnect()));

     //上线用户添加到客户列表容器
     clients.append(mSocket);
     //把用户添加到界面列表中
     QString ip = mSocket->peerAddress().toString().remove("::ffff:");//去除客户端中多余的字符
     ui->onlineUserList->addItem(ip);

     //在线数量添加
     onNum++;
     ui->onlineUserCount->setText(QString::number(onNum));//显示在线数

 }

 //接收数据
 void  mytcp::recv_data()
 {
       QTcpSocket *obj = (QTcpSocket*)sender();
       //获取发送数据端的IP
       QString ip = obj->peerAddress().toString();
       ip.remove("::ffff:");
       QString msg = obj->readAll();
       ui->receiveList->addItem(ip+":"+msg);//显示接收到的数据
       recvSize += msg.size();//统计接收到的数据的字节数
      ui->receiveNumLabel->setText(QString::number(recvSize));
 }

 void mytcp::client_disconnect()
 {
     QTcpSocket *obj = (QTcpSocket*)sender();//获取掉线对象
     if(isServer)
     {
         int row = clients.indexOf(obj);//找到掉线对象的内容所在的行
         QListWidgetItem *item = ui->onlineUserList->takeItem(row);//从界面列表中去除找到的一行内容
         delete item;
         clients.remove(row);//从容器中删除对象

         //掉线时删除在线数量
         onNum--;
        ui->onlineUserCount->setText(QString::number(onNum));
     }
     else
     {
         ui->StartBt->setEnabled(true);//断开连接的时候重新启用开始按钮
     }
 }


 //客户端连接成功
 void mytcp::connect_suc()
 {
     ui->StartBt->setEnabled(false);//连接成功则禁用开始按钮
     qDebug() << "建立连接成功";
 }

 //定时器定时发送数据
 void mytcp::auto_time_send()
 {
     qint64 len = mSocket->write(ui->sendMsgEdit->toPlainText().toUtf8());
     if(len > 0)
     {
        sendSize += len;//统计发送的字节数
         ui->sendNumLabel->setText(QString::number(sendSize));//把发送的字节数显示到sendNumLabel上
     }
 }

 //选择作为服务器
 void mytcp::on_severRB_clicked()
 {
     this->isCheckServer = true;
     this->isServer = true;
     //获取本地ip显示在IpEdit中
    ui->IpEdit->setText(QHostAddress(QHostAddress::LocalHost).toString());
    ui->IpEdit->setEnabled(false);//关闭ip输入编辑器
    this->isCheckClient = false;
     qDebug() << "选中了服务器";

 }

 //选择作为客户端
 void mytcp::on_clientRB_clicked()
 {
     this->isCheckClient = true;
     this->isServer = false;
     ui->IpEdit->setEnabled(true);//打开ip输入编辑器
     this->isCheckServer = false;
     qDebug() << "选中了客户端";

 }


 //启动服务器或者连接服务器
 void mytcp::on_StartBt_clicked()
 {
     if(isServer) //服务器
     {
         qDebug() << "正在开启服务器";
         mServer = new QTcpServer();
         //关联新客户端链接信号
         connect(mServer,SIGNAL(newConnection()),this,SLOT(accept_connect()));
         mServer->listen(QHostAddress::Any,ui->PortEdit->text().toInt());//启动服务器监听
         ui->StartBt->setEnabled(false);//开始按钮禁用
         qDebug() << "开启成功,正在监听。";
     }
     if(!isServer) //客户端
     {
         qDebug() << "正在连接服务器";
         mSocket = new QTcpSocket();

         //设置服务器的 ip和端口号
         mSocket->connectToHost(ui->IpEdit->text(),ui->PortEdit->text().toInt());
         //检测链接成功信号

         if (mSocket->waitForConnected(1000))  // 连接成功则进入if{}
         {
            qDebug() << "连接成功";
         }
         connect(mSocket,SIGNAL(connected()),this,SLOT(connect_suc()));

         connect(mSocket, SIGNAL(error(QAbstractSocket::SocketError)), \
                    this, SLOT(ReadError(QAbstractSocket::SocketError)));
         //关联接收数据信号
        connect(mSocket,SIGNAL(readyRead()),this,SLOT(recv_data()));
         //关联掉线信号
         connect(mSocket,SIGNAL(disconnected()),this,SLOT(client_disconnect()));
     }

     if(isCheckServer == false && isCheckClient == false)//如果两个都没选择
     {
        QMessageBox::warning(this,"提示","请选择服务器或者客户端");
         ui->StartBt->setEnabled(true);
         return;
     }

     if(isCheckServer)//选择了服务器
     {
        if(ui->PortEdit->text().isEmpty() || ui->PortEdit->text() == "请输入端口号")
        {
            QMessageBox::warning(this,"提示","请输入端口号");
            ui->StartBt->setEnabled(true);
            return;
        }
     }

    if(isCheckClient)//选择了客户端
     {
         if(ui->IpEdit->text().isEmpty() || ui->IpEdit->text() == "请输入ip" || ui->IpEdit->text() == "请输入端口号")
         {
             QMessageBox::warning(this,"提示","请输入ip和端口号");
             ui->StartBt->setEnabled(true);
             return;
         }
     }

 }

 //关闭服务器或者断开
 void mytcp::on_closeBt_clicked()
 {
     if(isServer)//服务器
     {
         for(int i=0;i<clients.count();i++)
         {
              clients.at(i)->close();//关闭所有客户端
         }

         //关闭所有服务器之后开始按钮才能启用
         mServer->close();
         ui->StartBt->setEnabled(true);
     }
     else //客户端
     {
         mSocket->close();//关闭客户端
         ui->StartBt->setEnabled(true);//启用开始按钮
     }

 }

 //双击选择要发送的客户端
 void mytcp::on_onlineUserList_doubleClicked(const QModelIndex &index)
 {
     mSocket = clients.at(index.row());

 }

 //自动发送数据
 void mytcp::on_autoCB_clicked(bool checked)
 {
     if(checked)

     {
         if(ui->autoTimeEdit->text().toInt() <= 0)
         {
             QMessageBox::warning(this,"提示","请输入时间值ms");
             ui->autoCB->setChecked(false);//把按钮重新置于没选中的状态
             return;
         }
         mTimer->start(ui->autoTimeEdit->text().toInt());//启动定时器
     }
     else
     {
         mTimer->stop();//停止定时器
     }

 }

 //手动发送数据
 void mytcp::on_sendMsgBt_clicked()
 {
     auto_time_send();

 }

 //清空接收区
 void mytcp::on_clearRcvBt_clicked()
 {
     ui->receiveNumLabel->clear();
     this->recvSize = 0;
     ui->receiveNumLabel->setText(QString::number(recvSize));
 }

 //清空发送区
 void mytcp::on_clearSendBt_clicked()
 {
     ui->sendNumLabel->clear();
     this->sendSize = 0;
     ui->sendNumLabel->setText(QString::number(sendSize));
 }


 //错误显示槽函数
 void mytcp::ReadError(QAbstractSocket::SocketError)
 {
     mSocket->disconnectFromHost();
     QMessageBox msgBox;
     msgBox.setText(tr("failed to connect server because %1").arg(mSocket->errorString()));
 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值