私は現在、マルチプレイヤーゲームのネットワーキングの一部を書こうとしています。私は、SFMLのコピー不可能なTCPソケットを格納する問題に直面しています(私は初心者ですC++)。SFMLで複数のクライアントソケットを扱う
私は三つのクラスがあります。Server
、Client
すべてのクライアントを格納し、それらのIDを与えることを担当している(サーバー側の接続クライアントに関するすべての情報を格納するために使用されるクラス)とClientManager
、など
をクライアントが接続したときに、私はもともと行うことを計画何ClientManager.h
class ClientManager {
public:
ClientManager();
std::map<int, Net::Client*> getClients();
int attribID();
void addClient(Net::Client *client);
sf::TcpSocket getClientSocket(int id) throw(std::string);
void setClientSocket(int id, sf::TcpSocket);
private:
std::map<int, Net::Client*> m_clients;
std::map<int, sf::TcpSocket> m_clientSockets;
std::vector<int> m_ids;
int m_lastID;
};
、次のとおりです。
void Net::Server::waitForClient() {
while(true) {
if(m_listener.accept(m_tcpSocket) != Socket::Done) {
cout << "Error happened during client connection. skipping. " << endl;
return;
}
int newID = m_clientManager.attribID();
this->m_clientManager.addClient(new Net::Client(newID, m_tcpSocket, m_tcpSocket.getRemoteAddress()));
}
}
したがって、新しいClient
をClientManagerのリストに追加します。そのIDは、情報とそのアドレスを送信するTcpSocketです。
しかし、SFMLのTcpSocketクラスはコピーできません。つまり、このようにクライアントにコピーすることはできません。
私はそれを元のTcpSocketへのポインタとして渡すことができましたが、他のクライアントが接続していればどうなりますか?ポインタが指すデータは変更され、プログラムはバグを起こします。この動作がスマートポインタと同じになるかどうかはわかりませんが、私はそう考えています(しかし、私はそれらを全く習得しません)。
std::map
またはstd::vector
にそれらを格納すると、両方ともオブジェクトがコピーされるため、同じ問題が発生します。ポインタを元のTcpSocketにポインタとして格納すると、以前と同じ問題が発生します。これは、ソケットも変更され、ポインタは同じオブジェクトを指しているためです。
リファレンス、ポインタを使用したりオブジェクトをコピーしたりせずにソケットを保存するにはどうすればよいですか?
すべてのヘルプは大歓迎されます:)
私は家に帰るときにこれ以上見る必要があります。ソケットのアドレスをclientManagerに渡してから、ソケットとIP情報を取得して保存してください。 – Eddge
std :: unique_ptrまたはshared_ptrを使用して動的メモリを使用し、ベクトル/マップにポインタを格納するだけで済みます(これにより、接続ごとにメモリを割り当てる必要があります)。 – Eddge
ご回答いただきありがとうございます!実際には、新たに接続されたすべてのクライアントにメモリを割り当てる必要があります(または、ポインタのケースをちょうど満たします)。メモリを割り当てることによって、whileループの先頭に 'shared_ptr'ポインタを作成し、' new'でメモリを割り当て、 'std :: map>'(または他の 'shared_ptr'を使って他の方法で)' ClientManager'に保存しますか? –
cocosushi