我正在制作一个简单的在线游戏,但我遇到了不同步的问题。服务器采用 IOCP 实现,由于游戏几乎总是在 LAN 中进行,因此延迟相对较小。
网络连接的核心算法可以描述如下:(一个fam有4个client)
- 客户端每帧将他们的动作和自上一帧以来经过的时间发送到服务器,然后等待服务器的响应。
- 服务器收集所有四个客户端的消息,将它们连接在一起,然后将其发送给所有四个客户端。
- 收到响应后,客户端会使用响应中提供的消息更新他们的游戏。
现在,我可以看到一段时间后,这四场比赛不同步了。可以观察到我所控制的游戏与其他三个不同(这意味着其他三个是相同的),只是通过走动就会出现问题。
下面是代码,如果它可能有帮助:
首先,服务器。每条消息都将在单独的线程中处理。
while(game_host[now_roomnum].Ready(now_playernum)) // wait for the last message to be taken away
{
Sleep(1);
}
game_host[now_roomnum].SetMessage(now_playernum, recv_msg->msg);
game_host[now_roomnum].SetReady(now_playernum, true);
game_host[now_roomnum].SetUsed(now_playernum, false);
while(!game_host[now_roomnum].AllReady()) // wait for all clients' messages
{
Sleep(1);
}
string all_msg = game_host[now_roomnum].GetAllMessage();
game_host[now_roomnum].SetUsed(now_playernum, true);
while(!game_host[now_roomnum].AllUsed()) // wait for all four responses are ready to send
{
Sleep(1);
}
game_host[now_roomnum].SetReady(now_playernum, false);// ready for receiving the next message
strcpy_s(ret.msg, all_msg.c_str());
和客户的CGame::Update(float game_time)
方法:
CMessage msg = MakeMessage(game_time);//Make a message with the actions taken in the frame(pushed into a queue) and the elasped time between the two frames
CMessage recv = p_res_manager->m_Client._SendMessage(msg);//send the message and wait for the server's response
stringstream input(recv.msg);
int i;
rest_time -= game_time;
float game_times[MAX_PLAYER+1]={0};
//analyze recv operations
for(i=1; i<=MAX_PLAYER; i++)
{
int n;
input>>n;
input>>game_times[i];//analyze the number of actions n, and player[i]'s elasped game time game_times[i]
for(int oper_i = 1; oper_i <= n; oper_i++)
{
int now_event;
UINT nchar;
input>>now_event>>nchar;
if(now_event == int(Event::KEY_UP))
HandleKeyUpInUpdate(i, nchar);
else //if(now_event == int(Event::KEY_DOWN))
HandleKeyDownInUpdate(i, nchar);
}
}
//update player
for(i=1; i<=MAX_PLAYER; i++)
{
player[i].Update(game_times[i]);//something like s[i] = v[i] * game_time[i]
}
非常感谢。如果需要,我会提供更多细节。