TCP协议是经常使用的通信方式。在QT中做了非常友好的封装,使用非常方便。
需要添加的模块:network
Qt中的TCP类:QTcpSocket , QTcpServer
常用函数介绍连接目标地址和端口
virtual void QTcpSocket ::connectToHost(const QHostAddress &address, quint16 port, OpenMode mode = ReadWrite);
发送数据
inline qint64 QTcpSocket ::write(const QByteArray &data)
监听某个地址和端口号
bool QTcpServer::listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0);
有新的连接信号
void QTcpServer::newConnection();
是否有新的连接
virtual bool QTcpServer::hasPendingConnections() const;
获取新的连接,必须处理完才能继续接收到连接
virtual QTcpSocket *QTcpServer::nextPendingConnection();
收到新的数据信号
void QTcpSocket::readyRead();
读取收到的数据,必须读取完才能继续接收
QByteArray readAll();
客户端
#include <QTcpSocket>
#include <QWidget>
#include <QLineEdit>
class Client : public QWidget
{
Q_OBJECT
public:
Client(QWidget *parent);
public slots:
void slotSendButtonClick();
private:
QTcpSocket *_socket;
QLineEdit *_lineEdit;
bool _isConnected;
};
#include "client.h"
#include <QPushButton>
#include <QHBoxLayout>
Client::Client(QWidget *parent)
: QWidget(parent)
{
_socket = new QTcpSocket(this);
_lineEdit = new QLineEdit(this);
QPushButton *sendButton = new QPushButton("send");
connect(sendButton, SIGNAL(clicked()), this, SLOT(slotSendButtonClick()));
connect(_lineEdit, SIGNAL(returnPressed()), this, SLOT(slotSendButtonClick()));
QHBoxLayout *lay = new QHBoxLayout(this);
lay->addWidget(_lineEdit);
lay->addWidget(sendButton);
_isConnected = false;
}
void Client::slotSendButtonClick()
{
if (!_isConnected)
{
_socket->connectToHost("127.0.0.1", 9988);
_isConnected = true;
}
QString text = _lineEdit->text();
if (!text.isEmpty())
{
_socket->write(text.toUtf8());//发送数据
_lineEdit->clear();
}
}
服务端
#include <QWidget>
#include <QTcpServer>
#include <QTcpSocket>
class QTextBrowser;
class Server :public QWidget
{
Q_OBJECT
public:
Server(QWidget *parent);
public slots:
void slotCurrentIndexChanged(const QString&);
void slotNewConnection();
private:
QTcpServer *_server;
QTcpSocket *_socket;
QTextBrowser *_textBrowser;
};
#include "server.h"
#include <QHostAddress>
#include <QTextBrowser>
#include <QByteArray>
#include <QGridLayout>
#include <QNetworkInterface>
#include <QComboBox>
Server::Server(QWidget *parent)
{
_server = new QTcpServer(this);
//_server->listen(QHostAddress::Any, 9988);//监听跟本主机相连的所有网口
connect(_server, SIGNAL(newConnection()),this, SLOT(slotNewConnection()) );
QList<QHostAddress> addrList = QNetworkInterface::allAddresses();
QComboBox *comboBox = new QComboBox;
for (const QHostAddress& addr : addrList)
{
quint32 ipAddr = addr.toIPv4Address();
if (ipAddr != 0)
{
comboBox->addItem(QHostAddress(ipAddr).toString());
}
}
connect(comboBox, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(slotCurrentIndexChanged(const QString&)));
_textBrowser = new QTextBrowser(this);
QGridLayout *lay = new QGridLayout(this);
lay->addWidget(comboBox, 0, 0);
lay->addWidget(_textBrowser,1,0);
}
void Server::slotCurrentIndexChanged(const QString& item)
{
if (!_server->isListening())
{
_server->listen(QHostAddress(item), 9988);
}
_textBrowser->append("listen...");
}
void Server::slotNewConnection()
{
_textBrowser->append("connecting...");
while (_server->hasPendingConnections())//必须处理完所有的连接,否则有新连接时就不会在发信号过来
{
_socket = _server->nextPendingConnection();
connect(_socket, &QTcpSocket::readyRead, [&]() {
_textBrowser->append("receive message...");
QByteArray newMessage = _socket->readAll();
_textBrowser->append(QString(newMessage));
});
}
}
使用效果