本文实例为大家分享了QT编写Server端的tcp通信工具的具体代码,供大家参考,具体内容如下1.说明使用qt写一个类似网上常见的网络调试工具。此篇为Server端。Client端在上一篇。2.基本流...

本文实例为大家分享了QT编写Server端的tcp通信工具的具体代码,供大家参考,具体内容如下

1.说明

使用qt写一个类似网上常见的网络调试工具。此篇为Server端。Client端在上一篇。

2.基本流程

新建QTcpServer对象,为其newConnection信号写槽函数。此为新的Client连接信号,在其对应槽函数里使用nextPendingConnection方法获取Client对象,并为Client添加readyRead(读数据),disconnected(断开连接)两个信号写槽函数。

开始监听使用Server的listen方法,停止监听使用Server的close方法。

主动断开某个连接可使用Client对象的disconnectFromHost方法。需要注意的是,这会触发disconnected信号。应小心处理,避免重复删除链表,导致程序崩溃。

3.代码

这是mainwindow.cpp文件

#include "mainwindow.h"
#include <QApplication>

MainWindow::MainWindow(QWidget *parent) :
  QMainWindow(parent),
  ui(new Ui::MainWindow)
{
  ui->setupUi(this);
  ui->splitter->setStretchFactor(0,2);
  ui->splitter->setStretchFactor(1,1);
  tcpServer = new QTcpServer(this);
  //qWarning()<<QNetworkInterface().allAddresses();
  QString ip=getLocalip();
  if( ip.isEmpty() )
  {
    QMessageBox::about(this,tr("提示"),tr("无本地IP。") ) ;
  }
  else{

    ui->ledtIp->setText( ip );  //本地IP
  }
  ui->labHostName->setText(tr("HostName:")+ QHostInfo::localHostName() );
  ui->labHostName->adjustSize();
  ui->ledtPort->setText(tr("8080"));
  ui->btnOpen->setEnabled(true);
  ui->btnSend->setEnabled(false);
  iplistMenu = new QMenu( ui->lwdgClientsIp );
  iplistMenu->addAction(ui->actiondel);
  connect( ui->actiondel, SIGNAL(triggered()), this, SLOT(slot_delmenu()));
  connect(tcpServer, SIGNAL(newConnection()), this, SLOT(slot_newConnectionClient()));
}

MainWindow::~MainWindow()
{
  delete ui;
}
//获取本地IP
/*
QString MainWindow::getLocalip()
{
  QHostInfo info = QHostInfo::fromName( QHostInfo::localHostName() );
  foreach(QHostAddress addr,info.addresses())
  {
    if(addr.protocol()==QAbstractSocket::IPv4Protocol)
    {
      return addr.toString();
    }
  }
  return "";
}
*/
QString MainWindow::getLocalip()
{
  QList<QHostAddress> list = QNetworkInterface::allAddresses();
  foreach (QHostAddress address, list)
  {
    if( address.protocol() == QAbstractSocket::IPv4Protocol)
    {
      return address.toString();
    }
  }
    return "";
}

//处理来自新的client连接
void MainWindow::slot_newConnectionClient()
{
  while (tcpServer->hASPendingConnections())
  {
    QTcpSocket *client = tcpServer->nextPendingConnection();
    tcpClients.append(client);

    ui->lwdgClientsIp->addItem( tr("%1:%2").arg(client->peerAddress().toString()).arg(client->peerPort()) );
    connect(client, SIGNAL(readyRead()), this, SLOT(slot_readData()));
    connect(client, SIGNAL(disconnected()), this, SLOT(slot_disconnectedClient()));
  }
}

//接收数据
void MainWindow::slot_readData()
{
  QTcpSocket *obj = (QTcpSocket*)sender();
  QByteArray buf = obj->readAll();
  if(buf.isEmpty())  return;

  QString ipc;
  ipc = tr("[%1:%2]>").arg(obj->peerAddress().toString()).arg(obj->peerPort());
  ui->teRecive->appendPlainText(ipc);
  ui->teRecive->appendPlainText(buf);
}

//断开连接处理
void MainWindow::slot_disconnectedClient()
{
  if( !tcpClients.isEmpty() ){
    QTcpSocket *obj = (QTcpSocket*)sender();
    QListWidgetItem *item = ui->lwdgClientsIp->findItems(
      tr("%1:%2")\
      .arg( obj->peerAddress().toString())\
      .arg( obj->peerPort()),Qt::MatchContains|Qt::MatchEndsWith
      ).at(0);

    ui->lwdgClientsIp->removeItemWidget( item );
    delete item;
    obj->close();
    tcpClients.removeOne(obj);
  }
}

//打开监听与停止
void MainWindow::on_btnOpen_clicked()
{
  if(ui->btnOpen->text() == "停止")//主动停止监听
  {

    if( !tcpClients.isEmpty() )
    for(int i=0; i<tcpClients.length(); i++)//断开所有连接
    {
      tcpClients[i]->disconnectFromHost(); //会触发disconnected信号
    }
    tcpClients.clear();
    tcpServer->close();
    ui->lwdgClientsIp->clear();
    ui->btnOpen->setText("监听");
    ui->btnSend->setEnabled(false);
  }else{ //打开监听
    if( ui->ledtPort->text().toInt() == 0 )
    {
      QMessageBox::about(this,tr("提示"),tr("请输入端口号。") ) ;
    }
    else
    if( tcpServer->listen( QHostAddress::AnyIPv4 , ui->ledtPort->text().toInt() ) )
    {
      ui->btnOpen->setText("停止");
      ui->btnSend->setEnabled(true);
    }
  }
}

//发送数据,UTF8模式
void MainWindow::on_btnSend_clicked()
{
  if( ui->lwdgClientsIp->selectedItems().length() >0 ){
    foreach( QListWidgetItem* item ,ui->lwdgClientsIp->selectedItems() )
    {
      QString clientIP = item->text().split(":")[0];
      int clientPort = item->text().split(":")[1].toInt();
      for(int i=0; i<tcpClients.length(); i++)
      {
        if(tcpClients[i]->peerAddress().toString()==clientIP && tcpClients[i]->peerPort()==clientPort)
        {
          tcpClients[i]->write(ui->teSend->toPlainText().toUtf8() );
          break;
        }
      }
    }
  }
}
//“删除”菜单,停止某个Client
void MainWindow:: slot_delmenu()
{
  if( lwdgitem != NULL )
  {
    if( !tcpClients.isEmpty() ){
      QString clientIP = lwdgitem->text().split(":")[0];
      int clientPort = lwdgitem->text().split(":")[1].toInt();
      for(int i=0; i<tcpClients.length(); i++)
      {
        if(tcpClients[i]->peerAddress().toString()==clientIP && tcpClients[i]->peerPort()==clientPort)
        {
          tcpClients[i]->disconnectFromHost();
          break;
        }
      }
    }
  }
}
//弹出菜单
void MainWindow::on_lwdgClientsIp_customContextMenuRequested(const QPoint &pos)
{
  lwdgitem=ui->lwdgClientsIp->itemAt(pos ) ;//判断是否在项目上
  if( lwdgitem != NULL )
  {
    iplistMenu->exec(QCursor::pos());
  }
}

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