您的位置:首页 > 理论基础 > 计算机网络

QTcpServer QTcpScoket通讯

2015-04-09 10:59 295 查看
最近需要一个数据转发的程序,昨天快下班之前看了QTcpServer和QTcpSocket模块,边看文档,边写了一个发送消息的demo。下完就下班了,今天早晨来测试,发现没什么问题。

QTcpServer 和QtcpSocket的封装,让我们写这类程序变得非常的简单了。

实例化一个QTcpServer对象,启动监听程序来监听某个端口。

有连接过来后,建立连接,然后通过这个链接进行通讯

因为QTcpSocket继承自QIOdevice 所以可以通过流的方式来操作,可以进行读写。

好了,先看看我写的demo的服务端

界面是随便的拖了一个按钮,堆起来的。



.h文件代码
#ifndef TCPSERVICETESTDLG_H
#define TCPSERVICETESTDLG_H

#include <QDialog>
#include <QMap>

class QTcpServer;
class QTcpSocket;

namespace Ui {
class TCPServiceTestDlg;
}

class TCPServiceTestDlg : public QDialog
{
Q_OBJECT
public:
explicit TCPServiceTestDlg(QWidget *parent = 0);
~TCPServiceTestDlg();
private:
void handleSendData(QTcpSocket * socket,const QString& msg); //处理发送数据
private slots:
void on_tb_start_clicked();//开始监听
//停止监听
void on_tb_stop_clicked();
//发送数据
void on_pb_send_clicked();
protected slots:
void slot_handleNewConnection();//处理连接
void slot_handleReciveData(); //接收数据
void slot_handleDisconnectSocket();//处理断开连接
private:
Ui::TCPServiceTestDlg *ui;
QTcpServer * server;
QMap<QString,QTcpSocket *> socketMap; //记录链接进来的ip
};

#endif // TCPSERVICETESTDLG_H

.cpp代码
#include "TCPServiceTestDlg.h"
#include "ui_TCPServiceTestDlg.h"
#include <QTcpServer>
#include <QTcpSocket>
#include <QDateTime>

TCPServiceTestDlg::TCPServiceTestDlg(QWidget *parent) :
QDialog(parent),
ui(new Ui::TCPServiceTestDlg)
{
ui->setupUi(this);
server = new QTcpServer(this);
connect(server,&QTcpServer::newConnection,this,&TCPServiceTestDlg::slot_handleNewConnection);
this->ui->tb_stop->setEnabled(false);
}

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

void TCPServiceTestDlg::handleSendData(QTcpSocket *socket, const QString &msg)
{
if(socket->isOpen())
{
QString sMsg = "发送:" + QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss") + msg;
QByteArray ba = sMsg.toUtf8();//用UTF8编码,要求服务端和客户端要用一样的编码,这样才能保证不会乱码
socket->write(ba);

}
}

void TCPServiceTestDlg::on_tb_start_clicked()
{

int prot = this->ui->sb_Port->value();
if(!server->listen(QHostAddress::Any,prot))
{
qDebug()<<server->errorString();
this->ui->tb_stop->setEnabled(false);
}
else
{
this->setWindowTitle("start success");
this->ui->tb_start->setEnabled(false);
this->ui->tb_stop->setEnabled(true);
}

}

void TCPServiceTestDlg::on_tb_stop_clicked()
{
if(server->isListening())
{
server->close();
this->ui->tb_start->setEnabled(true);
this->ui->tb_stop->setEnabled(false);
}
}

void TCPServiceTestDlg::slot_handleNewConnection()
{
QTcpSocket * socket = server->nextPendingConnection();
QString ipStr = socket->peerAddress().toString();
this->ui->lw_ip->addItem(ipStr);
socketMap.insert(ipStr,socket);
connect(socket,&QTcpSocket::disconnected,this,&TCPServiceTestDlg::slot_handleDisconnectSocket);
connect(socket,&QTcpSocket::readyRead,this,&TCPServiceTestDlg::slot_handleReciveData);
}

void TCPServiceTestDlg::slot_handleReciveData()
{
QTcpSocket * socket = dynamic_cast<QTcpSocket*>(sender());
if(socket!=NULL)
{
QString ipStr = socket->peerAddress().toString();
while(socket->bytesAvailable())
{
QByteArray vTemp=socket->readAll();
QString msg = ipStr + ":" + QString::fromUtf8(vTemp);
this->ui->te_reciveContent->append(msg);
}
}
}

/**
* @brief TCPServiceTestDlg::slot_handleDisconnectSocket
* 处理断开连接时的操作,断开连接时。把ip列表中断开的socket移除
* 同时把保存下来的socketMap中的socket移除,然后销毁socket
*/
void TCPServiceTestDlg::slot_handleDisconnectSocket()
{
QTcpSocket * socket = dynamic_cast<QTcpSocket*>(sender());
if(socket!=NULL)
{
QString ipStr = socket->peerAddress().toString();
if(socketMap.keys().contains(ipStr))
{
QList<QListWidgetItem*> items = this->ui->lw_ip->findItems(ipStr,Qt::MatchExactly);

foreach(QListWidgetItem *item , items)
{
this->ui->lw_ip->removeItemWidget(item);//remove后必须delete掉,不然界面上无法删除
delete item;
}
socketMap.remove(ipStr);
}
}
socket->deleteLater();
}

/**
* @brief TCPServiceTestDlg::on_pb_send_clicked
* 选定需要发送数据的ip,然后发送内容
*/
void TCPServiceTestDlg::on_pb_send_clicked()
{
QString text = this->ui->le_sendContent->text();
QList<QListWidgetItem*> items = this->ui->lw_ip->selectedItems();
foreach(QListWidgetItem * item ,items)
{
QTcpSocket * socket = socketMap.value(item->text());
if(socket!=NULL)
{
handleSendData(socket,text);
}
}

this->ui->le_sendContent->clear();
}
Pro文件代码
#-------------------------------------------------
#
# Project created by QtCreator 2015-04-08T16:20:07
#
#-------------------------------------------------

QT       += core gui network

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = ZTCPTEST
TEMPLATE = app

SOURCES += main.cpp\
TCPServiceTestDlg.cpp

HEADERS  += TCPServiceTestDlg.h

FORMS    += TCPServiceTestDlg.ui


客户端界面:



.h文件
#ifndef TCPCLIENTTESTDLG_H
#define TCPCLIENTTESTDLG_H

#include <QDialog>
class QTcpSocket;
namespace Ui {
class TCPClientTestDlg;
}

class TCPClientTestDlg : public QDialog
{
Q_OBJECT

public:
explicit TCPClientTestDlg(QWidget *parent = 0);
~TCPClientTestDlg();
public:
void handleSendData(QTcpSocket *socket, const QString &msg);
private slots:
void on_pBtnSend_clicked();

void on_pBtnConnect_clicked();

void on_pBtnDisconnect_clicked();

protected slots:
void slot_handleReciveData();

private:
Ui::TCPClientTestDlg *ui;
QTcpSocket * socket;
};

#endif // TCPCLIENTTESTDLG_H

.cpp文件
#include "TCPClientTestDlg.h"
#include "ui_TCPClientTestDlg.h"

#include <QTcpSocket>
#include <QHostAddress>
#include <QDateTime>
#include <QDebug>

TCPClientTestDlg::TCPClientTestDlg(QWidget *parent) :
QDialog(parent),
ui(new Ui::TCPClientTestDlg)
{
ui->setupUi(this);
socket = new QTcpSocket(this);

connect(socket,&QTcpSocket::readyRead,this,&TCPClientTestDlg::slot_handleReciveData);
this->ui->pBtnDisconnect->setEnabled(true);
}

void TCPClientTestDlg::handleSendData(QTcpSocket *socket, const QString &msg)
{
if(socket->isOpen())
{
QString sMsg = "发送:" + QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss") + msg;
QByteArray ba = sMsg.toUtf8();
socket->write(ba);
}
}

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

void TCPClientTestDlg::on_pBtnSend_clicked()
{
if(socket->isOpen())
{
QString text = this->ui->le_sendTest->text();
handleSendData(socket,text);
}
}

void TCPClientTestDlg::slot_handleReciveData()
{
while(socket->bytesAvailable())
{
QByteArray vTemp=socket->readAll();
QString msg = QString::fromUtf8(vTemp);
qDebug()<<msg;
}
}

void TCPClientTestDlg::on_pBtnConnect_clicked()
{
QString ip = this->ui->lineEdit->text();
int port = this->ui->spinBox->value();

QHostAddress address(ip);

socket->connectToHost(address,port);
this->ui->pBtnConnect->setEnabled(false);
this->ui->pBtnDisconnect->setEnabled(true);
}

void TCPClientTestDlg::on_pBtnDisconnect_clicked()
{
socket->disconnectFromHost();
this->ui->pBtnConnect->setEnabled(true);
this->ui->pBtnDisconnect->setEnabled(false);
}

Pro文件
#-------------------------------------------------
#
# Project created by QtCreator 2015-04-08T17:30:54
#
#-------------------------------------------------

QT       += core gui network

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = ZTCPClientTest
TEMPLATE = app

SOURCES += main.cpp\
TCPClientTestDlg.cpp

HEADERS  += TCPClientTestDlg.h

FORMS    += TCPClientTestDlg.ui


花了一点时间来写这个,内容比较粗糙,很多问题可能没有遇到和考虑到,以后需要详细的需求在增加。

运行效果界面:

1. 服务端启动监听

2. 客户端填写服务端ip地址,建立连接

3. 发送消息



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  QTcpServer QTcpSocke