1) キーがクライアント IP で、値がアカウント ID である std::map があります。認証後、サーバーはクライアントの IP とそのアカウント ID をこのマップに格納し、後でサーバーがクライアントから要求を受信すると、その IP をチェックしてマップで検索します。
IP 自体は十分ではありません。同じ IP から接続している複数の異なるクライアントが存在する可能性があります (まったく同じコンピューターから、または NAT IP のみが表示されるように NAT の背後にある別のコンピューターから)。IP に基づく一意のキーが必要な場合は、クライアントの IP/ポート タプルを使用する必要があります。
2) キーがランダムに生成されたキーで、値がアカウント ID である std::map があります。認証後、サーバーはこの特定のクライアントのランダム キーを生成し、このキーをクライアントに送信します。クライアントはそれを後で使用するために保存し、サーバーはこのキーとアカウント ID をマップに格納します。
これは非常に危険です。クライアントが別のクライアントの「セッション ID」を自分のセッション ID ではなく送信することを禁止し、他のクライアントのセッションをハイジャックするのはなぜでしょうか? これは、HTTP セッション ハイジャックとまったく同じ問題です。要するに、回避できる場合はそうしないでください。
その他の可能な解決策:
引き続きstd::map
ソケットハンドルをキーとして使用できます。これはサーバー上で必ず一意であるため、混乱が生じる可能性はなく、メッセージごとにクライアントの IP/ポートを取得する手間が省けます。
サーバーが古き良き「接続ごとに 1 つのスレッド」モデルを使用している場合、それらのフープをジャンプする必要はありません。セッション データを Thread Local Storage 変数に関連付けるだけで完了です。あるいは、ほとんどすべてのスレッド ライブラリで、特定のデータをスレッドに関連付けるために使用できるパラメーターをスレッドに渡すことができます (以下の例を参照)。
サーバーが古き良き「接続ごとに1つのプロセス」モデル(フォーク)を使用している場合は、さらに簡単です。各プロセスには独自の変数があるため、特別なことは何もありません。
残念ながら、あなたのサーバーが使用するモデル (スレッド化、分岐、選択、aio など) がわからない限り、あなたの質問は非常に自由なので、明確な答えを出すのは困難です。
スレッド化されたモデルを使用している場合、これが(大まかに)私が通常行う方法です(C ++ 11スレッドですが、他のスレッド化ライブラリでも同様に実行できます):
class ClientSession {
public:
ClientSession(int sock)
: m_sock(sock),
m_thread(&ClientSession::threadFunction, this)
{
}
private:
int m_sock;
WhateverType m_someSessionVariable;
std::thread m_thread; // the thread object should be declared last so that
// it is initialised last in the constructor, thus avoiding race conditions
// during the initialisation (you really don't want the thread to access
// your member variables if they are not yet initialised!)
static void threadFunction(ClientSession* object) {
object->threadMethod();
}
void threadMethod() {
// handle your connection
// the current ClientSession object (this) *is* your session
// put whatever you want in it, eg. m_someSessionVariable
}
};
//...
int sock_client = TEMP_FAILURE_RETRY(accept(sock_server, 0, 0));
if (sock_client >= 0)
new ClientSession(sock_client);
警告:明らかに、このコードには欠陥があります。ClientSession オブジェクトを破棄することはないため、メモリ リークが発生しますが、私のポイントは、スレッドを特定のセッション オブジェクトに関連付ける方法を示すことでした。オブジェクトの有効期間を管理するのはあなたに任せます。正確なアーキテクチャとニーズに応じて。