XNA: Networking gone totally out of sync
- by MesserChups
I'm creating a multiplayer interface for a game in 2D some of my friends made, and I'm stuck with a huge latency or sync problem.
I started by adapting my game to the msdn xna network tutorial and right now when I join a SystemLink network session (1 host on PC and 1 client on Xbox) I can move two players, everything is ok, but few minutes later the two machines start being totally out of synchronization. When I move one player it takes 10 or 20 seconds (increasing with TIME) to take effect on the second machine.
I've tried to :
Create a thread which calls NetworkSession.Update() continuously as suggested on this forum, didn't worked.
Call the Send() method one frame on 10, and the receive() method at each frame, didn't worked either.
I've cleaned my code, flushed all buffers at each call and switched the host and client but the problem still
remain...
I hope you have a solution because I'm running out of ideas...
Thanks
SendPackets() code :
protected override void SendPackets()
{
if ((NetworkSessionState)m_networkSession.SessionState == NetworkSessionState.Playing) //Only while playing
{
//Write in the packet manager
m_packetWriter.Write(m_packetManager.PacketToSend.ToArray(), 0, (int)m_packetManager.PacketToSend.Position);
m_packetManager.ResetPacket(); //flush
//Sends the packets to all remote gamers
foreach (NetworkGamer l_netGamer in m_networkSession.RemoteGamers)
{
if (m_packetWriter.Length != 0)
{
FirstLocalNetGamer.SendData(m_packetWriter, SendDataOptions.None, l_netGamer);
}
}
m_packetWriter.Flush();//m
m_packetWriter.Seek(0, 0);
}
}
ReceivePackets() code :
public override void ReceivePackets()
{
base.ReceivePackets();
if ((NetworkSessionState)m_networkSession.SessionState == NetworkSessionState.Playing) //Only while playing
{
if (m_networkSession.LocalGamers.Count > 0) //Verify that there's at least one local gamer
{
foreach (LocalNetworkGamer l_localGamer in m_networkSession.LocalGamers)
{ //every LocalNetworkGamer must read to flush their stream
// Keep reading while packets are available.
NetworkGamer l_oldSender = null;
while (l_localGamer.IsDataAvailable)
{
// Read a single packet, even if we are the host, we must read to clear the queue
NetworkGamer l_newSender;
l_localGamer.ReceiveData(m_packetReader, out l_newSender);
if (l_newSender != l_oldSender)
{
if ((!l_newSender.IsLocal) && (l_localGamer == FirstLocalNetGamer))
{
//Parsing PacketReader to MemoryStream
m_packetManager.Receive(new MemoryStream(m_packetReader.ReadBytes(m_packetReader.Length)));
}
}
l_oldSender = l_newSender;
m_packetReader.BaseStream.Flush();
m_packetReader.BaseStream.Seek(0, SeekOrigin.Begin);
}
}
m_packetManager.ParsePackets();
}
}
}