区別する必要があるのは言語のデータ構造タイプではないと思いますが、それは送信するデータに関するものです。言語が異なれば、言語構造なども異なる場合があることに注意してください。それは本当に低レベルの詳細です。それよりも重要なのは、あなたが何を送るかです。
QtCore の json 形式でシリアライゼーション/デシリアライゼーションがどのように機能するかを次の例で調べることができます。Json は json モジュールによって python でもサポートされているため、サーバー側で逆シリアル化する問題はありません。
JSON 保存ゲームの例
これは基本的に、クライアント側でいくつかのヒントを与える重要な部分です。ファイルへの保存に迷わないでください。基本的には、生のバイトをファイルに書き込みます。これは、ネットワーク経由で送信することで置き換えられます。
void Game::write(QJsonObject &json) const
{
QJsonObject playerObject;
mPlayer.write(playerObject);
json["player"] = playerObject;
QJsonArray levelArray;
foreach (const Level level, mLevels) {
QJsonObject levelObject;
level.write(levelObject);
levelArray.append(levelObject);
}
json["levels"] = levelArray;
}
...そして、サーバー側でこのようなことを行います。ファイルから読み取る代わりに、ネットワークから読み取ることになりますが、どちらもIOであるため、大したことではありません。
import json
json_data=open(file_directory).read()
data = json.loads(json_data)
pprint(data)
生のプロトコルを使用して独自のプロトコルを設計するか、単に拡張を使用することができます。http (tcp/udp) などの標準的なものを使用することをお勧めします。次に、独自のデータの json 形式を定義するだけでよく、片方向通信または双方向通信、リプライ攻撃に対するトランザクション識別子、タイムスタンプ、データ サイズなど、残りのすべてを処理する必要はありません。
これにより、本当に重要なことに集中することができます。独自のjson形式を定義したら、QtNetworkモジュールを調べて、必要に応じてpost、get、put、およびdeleteリクエストを送信できます。
おそらく、 QNetworkManager、QNetworkReplyクラスなどと密接に連携するでしょう。ここでは、単純なペーストビン機能のための QtCore の json を使用した Qt での単純なクライアント実装を見つけることができます。
#include <QSslError>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QTcpSocket>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonParseError>
#include <QFile>
#include <QScopedPointer>
#include <QTextStream>
#include <QStringList>
#include <QCoreApplication>
#include <QDebug>
int main(int argc, char **argv)
{
QCoreApplication application{argc, argv};
application.setOrganizationName(R"("CutePaste")");
application.setApplicationName(R"("CutePaste Desktop Console Frontend")");
QTextStream standardOutputStream{stdout};
QFile dataFile;
QString firstArgument{QCoreApplication::arguments().size() < 2 ? QString() : QCoreApplication::arguments().at(1)};
if (!firstArgument.isEmpty()) {
dataFile.setFileName(firstArgument);
dataFile.open(QIODevice::ReadOnly);
} else {
dataFile.open(stdin, QIODevice::ReadOnly);
}
QByteArray pasteTextByteArray{dataFile.readAll()};
QJsonObject requestJsonObject;
requestJsonObject.insert(QStringLiteral("data"), QString::fromUtf8(pasteTextByteArray));
requestJsonObject.insert(QStringLiteral("language"), QStringLiteral("text"));
QJsonDocument requestJsonDocument{requestJsonObject};
QString baseUrlString{QStringLiteral(R"("http://pastebin.kde.org")")};
QNetworkRequest networkRequest;
networkRequest.setAttribute(QNetworkRequest::DoNotBufferUploadDataAttribute, true);
networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, R"("application/json")");
networkRequest.setUrl(QUrl(baseUrlString + R"("/api/json/create")"));
QNetworkAccessManager networkAccessManager;
QScopedPointer<QNetworkReply> networkReplyScopedPointer(networkAccessManager.post(networkRequest, requestJsonDocument.toJson()));
QObject::connect(networkReplyScopedPointer.data(), &QNetworkReply::finished, [&] {
QJsonParseError jsonParseError;
QByteArray replyJsonByteArray{networkReplyScopedPointer->readAll()};
QJsonDocument replyJsonDocument{QJsonDocument::fromJson(replyJsonByteArray, &jsonParseError)};
if (jsonParseError.error != QJsonParseError::NoError) {
qDebug() << R"("The json network reply is not valid json:")" << jsonParseError.errorString();
QCoreApplication::quit();
}
if (!replyJsonDocument.isObject()) {
qDebug() << R"("The json network reply is not an object")";
QCoreApplication::quit();
}
QJsonObject replyJsonObject{replyJsonDocument.object()};
QJsonValue resultValue{replyJsonObject.value(QStringLiteral("result"))};
if (!resultValue.isObject()) {
qDebug() << R"("The json network reply does not contain an object for the "result" key")";
QCoreApplication::quit();
}
QJsonValue identifierValue{resultValue.toObject().value(QStringLiteral("id"))};
if (!identifierValue.isString()) {
qDebug() << R"("The json network reply does not contain a string for the "id" key")";
QCoreApplication::quit();
}
endl(standardOutputStream << baseUrlString << '/' << identifierValue.toString());
QCoreApplication::quit();
});
QObject::connect(networkReplyScopedPointer.data(), static_cast<void (QNetworkReply::*)(QNetworkReply::NetworkError)>(&QNetworkReply::error), [&](QNetworkReply::NetworkError networkReplyError) {
if (networkReplyError != QNetworkReply::NoError)
endl(standardOutputStream << networkReplyScopedPointer->errorString());
});
QObject::connect(networkReplyScopedPointer.data(), &QNetworkReply::sslErrors, [&](QList<QSslError> networkReplySslErrors) {
if (!networkReplySslErrors.isEmpty()) {
for (const auto &networkReplySslError : networkReplySslErrors)
endl(standardOutputStream << networkReplySslError.errorString());
}
});
int returnValue{application.exec()};
dataFile.close();
if (dataFile.error() != QFileDevice::NoError)
endl(standardOutputStream << dataFile.errorString());
return returnValue;
}
JSON は次のように定義されています。
http://sayakb.github.io/sticky-notes/pages/api/
確かに、これが唯一の方法ではありません。たとえば、効率が必要な場合は、capnprotoのようなバイナリ形式を検討することをお勧めします。