Qt之进程间通信(TCP/IP)
2016-02-04 10:19
405 查看
简述
可以通过Qt提供的IPC使用TCP/IP,使用QtNetwork模块即可实现,TCP/IP在实现应用程序和进程内部通信或与远程进程间的通信方面非常有用。QtNetwork模块提供的类能够创建基于TCP/IP的客户端与服务端应用程序。为实现底层的网络访问,可以使用QTcpSocket、QTcpServer和QUdpSocket,并提供底层网络类。还提供了使用常规协议实现网络操作的QNetworkRequest、QNetworkReply、QNetworkAccessManager。
简述
QtNetwork
Server
Client
QtNetwork
作为使用IPC的方法,TCP/IP可以使用多种类进行进程内部和外部的通信。QtNetwork模块提供的类:
类 | 说明 |
---|---|
QLocalServer | 基于服务器的本地套接字的类 |
QLocalSocket | 支持本地套接字的类 |
QNetworkAccessManager | 处理从网络首发收据响应的类 |
QSocketNotifier | 监控从网络通知消息的类 |
QSsl | 在所有网络通信上用于SSL认证的类 |
QSslSocket | 支持通过客户端和服务器端加密的套接字的类 |
QTcpServer | 基于TCP的服务器端类 |
QTcpSocket | TCP套接字 |
QUdpSocket | UDP套接字 |
下面我们来看一个示例,可以在Creator自带的示例中查找QLocalSocket或Local Fortune。
Server
首先,启动Server,这是必然的,服务端不开启,客户端怎么连接得上呢?server = new QLocalServer(this); // 告诉服务器监听传入连接的名字。如果服务器当前正在监听,那么将返回false。监听成功返回true,否则为false if (!server->listen("fortune")) { QMessageBox::critical(this, tr("Fortune Server"), tr("Unable to start the server: %1.") .arg(server->errorString())); close(); return; } fortunes << tr("You've been leading a dog's life. Stay off the furniture.") << tr("You've got to think about tomorrow.") << tr("You will be surprised by a loud noise.") << tr("You will feel hungry again in another hour.") << tr("You might have mail.") << tr("You cannot kill time without injuring eternity.") << tr("Computers are not intelligent. They only think they are."); // 有新客户端进行连接时,发送数据 connect(server, SIGNAL(newConnection()), this, SLOT(sendFortune())); // 发送数据 void Server::sendFortune() { // 从fortunes中随机取出一段字符串然后进行写入。 QByteArray block; QDataStream out(&block, QIODevice::WriteOnly); out.setVersion(QDataStream::Qt_4_0); out << (quint16)0; out << fortunes.at(qrand() % fortunes.size()); out.device()->seek(0); out << (quint16)(block.size() - sizeof(quint16)); // nextPendingConnection()可以返回下一个挂起的连接作为一个连接的QLocalSocket对象。 QLocalSocket *clientConnection = server->nextPendingConnection(); connect(clientConnection, SIGNAL(disconnected()), clientConnection, SLOT(deleteLater())); clientConnection->write(block); clientConnection->flush(); clientConnection->disconnectFromServer(); }
socket被当做server的孩子创建,这意味着,当QLocalServer对象被销毁时它也会被自动删除。这明显是一个删除对象的好主意,使用完成以后,避免了内存的浪费。
Client
启动客户端,连接到对应的服务器,如果连接不上,则进行错误处理。socket = new QLocalSocket(this); connect(getFortuneButton, SIGNAL(clicked()), this, SLOT(requestNewFortune())); connect(socket, SIGNAL(readyRead()), this, SLOT(readFortune())); connect(socket, SIGNAL(error(QLocalSocket::LocalSocketError)), this, SLOT(displayError(QLocalSocket::LocalSocketError))); // 连接到服务器,abort()断开当前连接,重置socket。 void Client::requestNewFortune() { getFortuneButton->setEnabled(false); blockSize = 0; socket->abort(); socket->connectToServer(hostLineEdit->text()); } // 读取服务器端发送的数据 void Client::readFortune() { // 读取接收到的数据 QDataStream in(socket); in.setVersion(QDataStream::Qt_4_0); if (blockSize == 0) { if (socket->bytesAvailable() < (int)sizeof(quint16)) return; in >> blockSize; } if (in.atEnd()) return; QString nextFortune; in >> nextFortune; // 如果当前的数据和收到的数据相同,则重新请求一次,因为是随机的字符串,所以肯定不会每次都相同。 if (nextFortune == currentFortune) { QTimer::singleShot(0, this, SLOT(requestNewFortune())); return; } currentFortune = nextFortune; statusLabel->setText(currentFortune); getFortuneButton->setEnabled(true); } // 发生错误时,进行错误处理 void Client::displayError(QLocalSocket::LocalSocketError socketError) { switch (socketError) { case QLocalSocket::ServerNotFoundError: QMessageBox::information(this, tr("Fortune Client"), tr("The host was not found. Please check the " "host name and port settings.")); break; case QLocalSocket::ConnectionRefusedError: QMessageBox::information(this, tr("Fortune Client"), tr("The connection was refused by the peer. " "Make sure the fortune server is running, " "and check that the host name and port " "settings are correct.")); break; case QLocalSocket::PeerClosedError: break; default: QMessageBox::information(this, tr("Fortune Client"), tr("The following error occurred: %1.") .arg(socket->errorString())); } getFortuneButton->setEnabled(true); }
相关文章推荐
- Android 网络请求Volley库完全解析,Volley的基本用法(二)
- 使用 obfsproxy 混淆网络流量
- 知名网络后端开源软件集合
- TCP服务器端和客户端程序设计
- HttpMessageNotWritableException: Could not write JSON: No serializer found for class ****
- https 后面补充session
- 2016SEM百度竞价如何分词【太原网络营销师】{郭文军}解析
- 厦门巨游网络科技有限公司(HOTPOWER)承接游戏UI外包
- #TCP你学得会# 之 当listen和accept遇到fork
- 网络工程 POST与GET请求方法的本质区别
- 基于TCP流协议的数据包通讯
- TCP与IP协议的相互作用
- https填坑之旅
- 【slighttpd】基于lighttpd架构的Server项目实战(2)—预备知识之libevent
- SPDY与HTTP2.0
- UITableView加载网络数据的优化
- Mstsc 远程桌面链接 And 网络映射
- NSUrl读取网络资源
- lighttpd-1.4.39 : array
- Could not find artifact plugin:jar in nexus http://localhost:8081/nexus/content/groups/public