Ok, having more problems. It's now sending the packets in order, but it's really buggy (it corrupts the packets). Also, the receive is also not working sometimes for those with bad ping and connection times.
How I handle dropped packets:
struct droppedPacket
{
std::list<sf::Packet*> spack;
sf::Int32 connectorID;
};
void NetworkManager::addDroppedPacket(sf::Packet* spack, sf::Int32 connectorID)
{
bool found = false;
for(sf::Int32 i = 0; i < droppedPackets.size(); i++)
{
if(droppedPackets[i].connectorID == connectorID)
{
found = true;
droppedPackets[i].spack.push_front(spack);
}
}
if(!found)
{
droppedPacket dp;
dp.spack.push_back(spack);
dp.connectorID = connectorID;
droppedPackets.push_back(dp);
}
}
void NetworkManager::retryDroppedPackets()
{
for(sf::Int32 i = 0; i < droppedPackets.size(); i++)
{
Connector* con = getConnectorWithID(droppedPackets[i].connectorID);
if(con != NULL) // client still online
{
sf::Socket::Status status = con->socket.send(*droppedPackets[i].spack.back());
if(status == sf::Socket::Done)
{
// packet sent correctly!
delete droppedPackets[i].spack.back();
droppedPackets[i].spack.pop_back();
if(droppedPackets[i].spack.empty())
droppedPackets.erase(droppedPackets.begin() + i);
}
else if(status == sf::Socket::Disconnected)
{
ent::playerHandler.handleDisconnect(ent::connectors[i]->getID());
}
else
{
// Packet did not send correctly
}
}
else // client disconnected
{
while(!droppedPackets[i].spack.empty())
{
delete droppedPackets[i].spack.back();
droppedPackets[i].spack.pop_back();
}
droppedPackets.erase(droppedPackets.begin() + i);
}
}
}
bool NetworkManager::doesConnectorHaveDroppedPacket(sf::Int32 connectorID)
{
for(sf::Int32 i = 0; i < droppedPackets.size(); i++)
{
if(droppedPackets[i].connectorID == connectorID)
return true;
}
return false;
}
How I handle the initial send:
bool Connector::sendPacket(sf::Packet* spack)
{
if(!ent::networkManager.doesConnectorHaveDroppedPacket(ID))
{
sf::Socket::Status status = socket.send(*spack);
if(status == sf::Socket::Done)
{
// packet sent correctly!
return true;
}
else
{
sf::Packet* spack2 = new sf::Packet(*spack);
ent::networkManager.addDroppedPacket(spack2, ID);
return false;
}
}
else
{
sf::Packet* spack2 = new sf::Packet(*spack);
ent::networkManager.addDroppedPacket(spack2, ID);
return false;
}
}
How I handle receives:
void NetworkManager::recPackets()
{
Connector* newConnector = new Connector;
newConnector->socket.setBlocking(false);
newConnector->player = NULL;
if(listener.accept(newConnector->socket) == sf::Socket::Done)
{
// Adds a new client to client list
maxConID += 1;
newConnector->setID(maxConID);
ent::connectors.push_back(newConnector);
}
else
{
// Nothing we can do...
delete newConnector;
}
// The listener socket is not ready, test all other sockets
for(sf::Int32 i = 0; i < ent::connectors.size(); i++)
{
sf::Packet packet;
sf::Socket::Status status = ent::connectors[i]->socket.receive(packet);
if(status == sf::Socket::Done)
{
ent::connectors[i]->logClock.restart();
sf::Uint32 packetCode;
packet >> packetCode;
handlePacket(packetCode, packet, ent::connectors[i]->getID());
}
else if(status == sf::Socket::Disconnected)
{
ent::playerHandler.handleDisconnect(ent::connectors[i]->getID());
}
else if(status == sf::Socket::Error)
{
std::cout << "NetworkingError";
}
else if(status == sf::Socket::NotReady)
{
// Not ready
//std::cout << "not ready";
}
}
}
Again, this (
mostly) only occurs when the other connector has a bad connection and high ping times. Know of any problems with this?