QTcpSocket 是 Qt 框架中的一个类,用于实现 TCP 协议的套接字。它提供了基于流的 TCP 套接字通信,可以用于客户端和服务器端的网络通信。QTcpSocket 可以发送和接收数据,支持同步和异步操作,还提供了一些方便的方法用于设置套接字选项和处理错误。
以下是一个使用 QTcpSocket 实现简单的客户端和服务器端通信的代码示例(同步):
客户端:
#include <QTcpSocket>
#include <QCoreApplication>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QTcpSocket socket;
socket.connectToHost("localhost", 1234); // 连接到本地主机的 1234 端口
if (!socket.waitForConnected()) {
qDebug() << "Error: " << socket.errorString();
return -1;
}
// 发送数据
QByteArray data = "Hello, server!";
socket.write(data);
// 等待数据接收
if (!socket.waitForReadyRead()) {
qDebug() << "Error: " << socket.errorString();
return -1;
}
// 接收数据
QByteArray receivedData = socket.readAll();
qDebug() << "Received data: " << receivedData;
socket.disconnectFromHost();
return a.exec();
}
服务器端:
#include <QTcpServer>
#include <QTcpSocket>
#include <QCoreApplication>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QTcpServer server;
if (!server.listen(QHostAddress::Any, 1234)) { // 监听所有地址的 1234 端口
qDebug() << "Error: " << server.errorString();
return -1;
}
qDebug() << "Server started, listening on port 1234...";
while (server.isListening()) {
if (server.waitForNewConnection()) {
QTcpSocket *socket = server.nextPendingConnection();
// 等待数据接收
if (!socket->waitForReadyRead()) {
qDebug() << "Error: " << socket->errorString();
socket->close();
continue;
}
// 接收数据
QByteArray receivedData = socket->readAll();
qDebug() << "Received data: " << receivedData;
// 发送数据
QByteArray data = "Hello, client!";
socket->write(data);
socket->disconnectFromHost();
}
}
return a.exec();
}
在这个示例中,我们首先创建了一个 QTcpServer 对象,并使用 `listen()` 方法监听所有地址的 1234 端口。如果监听失败,我们会打印出错误信息并返回 -1。
然后,我们使用 `waitForNewConnection()` 方法等待客户端的连接请求。如果有新的连接请求,我们使用 `nextPendingConnection()` 方法获取连接的 QTcpSocket 对象。
接着,我们使用 `waitForReadyRead()` 方法等待客户端发送的数据。如果等待失败,我们会打印出错误信息并关闭连接。如果接收到数据,我们使用 `readAll()` 方法读取数据,并打印出来。
最后,我们使用 `write()` 方法发送数据到客户端,并使用 `disconnectFromHost()` 方法关闭连接。
需要注意的是,这个示例是同步的,也就是说,程序会一直等待直到数据接收完成。如果需要异步操作,可以使用信号和槽机制实现。
------------------------------------------------------------------------------------
以下是一个使用 QTcpSocket 实现异步客户端和服务器端通信的代码示例:
客户端:
#include <QTcpSocket>
#include <QCoreApplication>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QTcpSocket socket;
socket.connectToHost("localhost", 1234); // 连接到本地主机的 1234 端口
QObject::connect(&socket, &QTcpSocket::connected, [&]() {
// 连接成功后发送数据
QByteArray data = "Hello, server!";
socket.write(data);
});
QObject::connect(&socket, &QTcpSocket::readyRead, [&]() {
// 接收数据
QByteArray receivedData = socket.readAll();
qDebug() << "Received data: " << receivedData;
socket.disconnectFromHost();
a.quit();
});
QObject::connect(&socket, &QTcpSocket::errorOccurred, [&]() {
qDebug() << "Error: " << socket.errorString();
a.quit();
});
return a.exec();
}
服务器端:
#include <QTcpServer>
#include <QTcpSocket>
#include <QCoreApplication>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QTcpServer server;
if (!server.listen(QHostAddress::Any, 1234)) { // 监听所有地址的 1234 端口
qDebug() << "Error: " << server.errorString();
return -1;
}
qDebug() << "Server started, listening on port 1234...";
QObject::connect(&server, &QTcpServer::newConnection, [&]() {
QTcpSocket *socket = server.nextPendingConnection();
QObject::connect(socket, &QTcpSocket::readyRead, [&]() {
// 接收数据
QByteArray receivedData = socket->readAll();
qDebug() << "Received data: " << receivedData;
// 发送数据
QByteArray data = "Hello, client!";
socket->write(data);
socket->disconnectFromHost();
});
QObject::connect(socket, &QTcpSocket::disconnected, [&]() {
socket->deleteLater();
});
QObject::connect(socket, &QTcpSocket::errorOccurred, [&]() {
qDebug() << "Error: " << socket->errorString();
socket->deleteLater();
});
});
return a.exec();
}
在这个示例中,我们使用了信号和槽机制实现了异步操作。客户端使用 `connect()` 方法连接到服务器端,然后分别连接了 `connected`、`readyRead` 和 `errorOccurred` 信号。当连接成功后,我们使用 `write()` 方法发送数据。当接收到数据时,我们使用 `readAll()` 方法读取数据,并打印出来。当连接出错时,我们打印出错误信息并退出程序。
服务器端使用 `newConnection` 信号来监听客户端的连接请求。当有新的连接请求时,我们使用 `nextPendingConnection()` 方法获取连接的 QTcpSocket 对象,然后分别连接了 `readyRead`、`disconnected` 和 `errorOccurred` 信号。当接收到数据时,我们使用 `readAll()` 方法读取数据,并打印出来。然后,我们使用 `write()` 方法发送数据到客户端,并使用 `disconnectFromHost()` 方法关闭连接。当连接断开时,我们使用 `deleteLater()` 方法释放 QTcpSocket 对象。当连接出错时,我们打印出错误信息并释放 QTcpSocket 对象。
需要注意的是,异步操作需要使用事件循环,因此我们在客户端和服务器端的最后都使用了 `a.exec()` 方法来启动事件循环。同时,我们也使用了 `a.quit()` 方法来退出事件循环。