- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个基于 Qt 的客户端/服务器应用程序,使用 QTcpServer 和 QTcpSocket,我设法建立连接并在客户端和客户端之间来回发送一些数据服务器。客户端向服务器发送多种类型的数据(字符串、整数、文件和实时音频流),因为我的服务器实现了单个数据输入 SLOT (readyRead()):
connect(socket, SIGNAL(readyRead()),this, SLOT(readyRead()));
我不知道如何区分所有这些接收到的数据并分别调用服务器中的正确函数。
Example (in the server):
- if I receive string => call function showData(QString data);
- if I receive file => call function saveFile(QFile file);
- if I receive audio stream => play audio stream
- ...
服务器:
void Server::newClientConnection()
{
QTcpSocket *socket = server->nextPendingConnection();
connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead()));
//...
}
void Server::readyRead()
{
QTcpSocket *clientSocket = qobject_cast<QTcpSocket *>(sender());
if (clientSocket == 0) {
return;
}
QDataStream in(clientSocket);
if (sizeMessageClient == 0)
{
if (clientSocket->bytesAvailable() < (int)sizeof(quint16)){
return;
}
in >> sizeMessageClient;
}
if (clientSocket->bytesAvailable() < sizeMessageClient) {
return;
}
sizeMessageClient = 0;
in >> data;
/*
I don't know the type of the received data !!
- if I receive string => call function showData(QString data);
- if I receive file => call function saveFile(QFile file);
- if I receive audio stream => play audio stream
- ...
*/
}
客户:
Client::Client()
{
socket = new QTcpSocket(this);
connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead()));
sizeMessageServer = 0;
}
void Client::readyRead()
{
QDataStream in(socket);
if (sizeMessageServer == 0)
{
if (socket->bytesAvailable() < (int)sizeof(quint16)) {
return;
}
in >> sizeMessageServer;
}
if (socket->bytesAvailable() < sizeMessageServer) {
return;
}
int messageReceived;
in >> messageReceived;
messageReceived = static_cast<int>(messageReceived);
sizeMessageServer = 0;
switch(messageReceived)
{
case 1:
qDebug() << "send a File";
sendFile();
break;
case 2:
qDebug() << "send a string data";
sendStringData();
break;
case 3:
qDebug() << "stream audio to the server";
streamAudioToServer();
break;
case n:
// ...
}
}
我不是在寻找一个完整的解决方案,我只是在寻找一些正确方向的指导。
最佳答案
您的协议(protocol)的实现没有完全利用 Qt 5.7 中的 QDataStream
。现在看起来可能是这样的 - 它可以非常简单。
首先,让我们定义我们知道的请求:
enum class Req : quint32 {
Unknown, String, File
};
Q_DECLARE_METATYPE(Req)
QDataStream & operator<<(QDataStream & ds, Req req) {
return ds << (quint32)req;
}
QDataStream & operator>>(QDataStream & ds, Req & req) {
quint32 val;
ds >> val;
if (ds.status() == QDataStream::Ok)
req = Req(val);
return ds;
}
拥有交易 RAII 助手也很方便。
struct Transaction {
QDataStream & stream;
Transaction(QDataStream & stream) : stream{stream} {
stream.startTransaction();
}
~Transaction() {
stream.commitTransaction();
}
bool ok() {
return stream.status() == QDataStream::Ok;
}
};
客户端接收来自服务器的请求并发出需要用数据回复的信号。使用客户端的代码会对这些信号使用react,并通过调用匹配的插槽进行回复。例如
void clientUser(Client & client) {
QObject::connect(&client, &Client::needString, &client, [&]{
client.sendString(QStringLiteral{"You got string!"});
});
和:
class Client : public QObject {
Q_OBJECT
QIODevice & m_dev;
QDataStream m_str{&m_dev};
void onReadyRead() {
Transaction tr{m_str};
Req req;
m_str >> req;
if (!tr.ok()) return;
if (req == Req::String)
emit needString();
else if (req == Req::File) {
QString fileName;
m_str >> fileName;
if (!tr.ok()) return;
emit needFile(fileName);
}
else emit unknownRequest(req);
}
public:
Client(QIODevice & dev) : m_dev{dev} {
connect(&m_dev, &QIODevice::readyRead, this, &Client::onReadyRead);
}
Q_SIGNAL void unknownRequest(Req);
Q_SIGNAL void needString();
Q_SIGNAL void needFile(const QString & fileName);
Q_SLOT void sendString(const QString & str) {
m_str << Req::String << str;
}
Q_SLOT void sendFile(const QString & fileName, const QByteArray & data) {
m_str << Req::File << fileName << data;
}
};
服务器非常相似。它的用户通过 request
槽向客户端发送请求。一旦服务器从客户端收到回复,它就会通过 has
信号表明它:
class Server : public QObject {
Q_OBJECT
QIODevice & m_dev;
QDataStream m_str{&m_dev};
void onReadyRead() {
Transaction tr{m_str};
Req req;
m_str >> req;
if (!tr.ok()) return;
if (req == Req::String) {
QString str;
m_str >> str;
if (!tr.ok()) return;
emit hasString(str);
}
else if (req == Req::File) {
QString fileName;
QByteArray data;
m_str >> fileName >> data;
if (!tr.ok()) return;
emit hasFile(fileName, data);
}
else emit hasUnknownRequest(req);
}
public:
Server(QIODevice & dev) : m_dev{dev} {
connect(&m_dev, &QIODevice::readyRead, this, &Server::onReadyRead);
}
Q_SIGNAL void hasUnknownRequest(Req);
Q_SIGNAL void hasString(const QString &);
Q_SIGNAL void hasFile(const QString & name, const QByteArray &);
Q_SLOT void requestString() {
m_str << Req::String;
}
Q_SLOT void requestFile(const QString & name) {
m_str << Req::File << name;
}
};
关于c++ - Qt,从客户端向服务器发送多种数据类型+数据流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39144556/
我想在一些计算机之间建立点对点连接,这样用户就可以在没有外部服务器的情况下聊天和交换文件。我的第一个想法如下: 我在服务器上创建了一个中央 ServerSocket,所有应用程序都可以连接到该服务器。
我正在 Unity 中构建多人游戏。为此,我必须将一些值从客户端发送到两个或多个通过服务器连接的客户端。我想将其构建为服务器真实游戏。客户端将使用 Android,他们的数据将通过服务器同步(可能是一
练习 C 网络编程:我正在编写一个简单的 TCP 客户端-服务器应用程序,它应该将消息(在每个客户端的单独线程中)作为字符串从服务器发送到客户端并在客户端(稍后将成为控制台商店应用程序)。我首先发送消
我使用证书身份验证设置了 AWS Client VPN。我正在为客户端-客户端访问系统进行设置,基本上如 this AWS scenario/example 中所述.一切正常,如果我知道他们的 IP
我正在开发一个小型客户端1/客户端2、服务器(线程)TCP 游戏。在尝试处理延迟问题时,我意识到我的 transmitState() 中存在缺陷。它强制将不必要的信息传递到通讯流中,从而造成迟缓,将汽
来自文档:Configurable token lifetimes in Azure Active Directory (Public Preview) 它提到“ secret 客户端”,刷新 tok
Apollo 客户端开发工具无法连接到我的应用程序。我已在 ApolloClient 构造函数中将 connectToDevTools 传递为 true,但没有任何 react 。我也试过this p
我想在 Pod 内使用 Fabric8 kubernetes 客户端 (java)。如何获取部署集群的 kubernetes 客户端? 我可以使用该集群的 kubeconfig 文件获取任何集群的配置
我正在阅读 the security issue with Log4j我了解此产品受此漏洞影响。但是 Oracle 客户端 11.2 和 12 是否受此问题影响? 我找不到这些产品是否使用任何 Log
Eureka 服务器设置 pom.xml 1.8 Hoxton.SR1 org.springframework.cloud spring
我有一个点对点(客户端/服务器)设置(通过本地 LAN),它使用 Netty,一个 Java 网络框架。我使用原始 TCP/IP(例如,没有 HTTP)进行通信和传输。现在,根据要求,我们希望转向 T
上一篇已经实现了ModbusTcp服务器和8个主要的功能码,只是还没有实现错误处理功能。 但是在测试客户端时却发现了上一篇的一个错误,那就是写数据成功,服务器不需要响应。 接下来要做的就是实现Modb
有没有办法将二维十六进制代码数组转换为 png 图像? 数组看起来像这样(只是更大) [ [ '#FF0000', '#00FF00' ], [ '#0000FF'
我是套接字编程的新手。每次我运行客户端程序时,它都会说“无法连接到服务器”。谁能告诉我我在哪里犯了错误。任何帮助将不胜感激。 这是client.c #include #include #inclu
我们在UNIX环境下制作了简单的client.c和server.c程序。我们使用它来传输一个简单的文本文件,首先打开它,然后读取它并使用 open、read 和 send 系统调用发送;在客户端,我接
当我的程序来自 my previous question正在响应客户端,它应该发送加密消息。 当客户端连接时,它会发送一条类似“YourMessage”的消息。现在我想做的是,当客户端连接时,应该以某
我正在使用 C 和 putty 编写客户端/服务器程序。两个 c 文件位于同一系统上。 我目前在向客户端写回其正在使用的框架以及打印我的框架时遇到问题。它打印出 3 0 9 8,但随后开始打印 134
我正在使用 C 中的 select() 制作一个模拟快餐或其他任何东西的客户端服务器。 我有客户随机点 1-5 种“食物”。服务器每 30 秒决定一次。所有客户最喜欢的食物是什么?他为那些客户提供服务
对于单机游戏,基本的游戏循环是(来源:维基百科) while( user doesn't exit ) check for user input run AI move enemies
1、CentOS安装TortoiseSVN 复制代码 代码如下: yum install -y subversion 2、SVN客户端命令
我是一名优秀的程序员,十分优秀!