我目前正在嘗試編寫一個小型多人遊戲的網絡部分,而且我面臨的問題是存儲我的TCP套接字,這些套接字在SFML中是不可複製的(我是一個初學者C++)。使用SFML處理多個客戶端套接字
我有三類:Server
,Client
和ClientManager
(用於存儲連接的客戶端所有信息的服務器端類),它負責存儲所有的客戶,並給他們的ID等
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,並將指針存儲在vector/map中(這將要求您爲每個連接分配內存)。 – Eddge
嘿,謝謝你的回答!它確實需要爲每個新連接的客戶端分配內存(或者我們只會遇到指針的情況)。通過分配內存,你的意思是:在while循環開始時創建一個'shared_ptr'指針,用'new'分配內存,然後有一個'std :: map>'(或任何其他方式與另一個'shared_ptr')將它們存儲在'ClientManager'中? –
cocosushi