本文实例为大家分享了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());
}
}