현재 멀티 플레이어 게임의 네트워킹 부분을 작성하려고하고 있습니다. SFML로 복사 할 수없는 TCP 소켓을 저장하는 데 문제가 있습니다. (초보자입니다. C++). Server
, Client
등 모든 클라이언트를 저장하고 그들에게 ID를 부여 담당하고 ClientManager
(모든 접속 클라이언트에 대한 정보를 저장하는 서버 측 클래스),SFML을 사용하여 여러 클라이언트 소켓 처리
:
난 세 종류를 클라이언트가 연결될 때 내가 원래 할 계획 무엇 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()));
}
}
따라서 ClientManager의 목록에 ID가있는 Client
을 추가하면 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