ich habe über die letzen Monate immer wieder ab und zu an meiner Netwerk-Klasse geschrieben. Diese funktioniert - auch durch die Hilfe dieses Forum - jetzt eigentlich perfekt. Ich habe nurnoch ein sehr eigenartiges Problem dessen Lösung ich einfach nicht finden kann.
Ich benutze TCP als Protokoll und select() um herauszufinden, ob es etwas zu lesen/schreiben gibt. Dies funktioniert auch einwandfrei außer mein Client hat einen Segfault (nicht aufgrund des Netzwerk-Codes). Dann kann es passieren dass der Server beim Lesen des Sockets segfaulted. Das selbe passiert dass beim Neustart des Servers und dem Aufruf von bind(). Ein sehr komisches Verhalten dass auch nicht immer auftritt.
Hier der Code zum Empfangen von Daten:
Code: Alles auswählen
void CTCPPort::processReceiving(PeerID id)
{
// Clear the buffer (global member)
memset(&buffer[0], 0, TCP_BUFFER_SIZE);
s32 readLength = recv( peers[id]->socketfd, &buffer[0], TCP_BUFFER_SIZE, 0);
if (readLength < 0)
{
#ifdef YOGI_WINDOWS
if(errno == WSAETIMEDOUT)
#else
if(errno == ETIMEDOUT)
#endif
this->getCallback()->onPeerDisconnect(id, NetworkInfo_ConnectionTimeout);
else
{
this->getCallback()->onPeerDisconnect(id, NetworkInfo_UnknownError);
if(logger)
//! Debugger sagt der Segfault passiert hier was aber an sich unlogisch scheint.
logger->log(ELMT_Warning, std::string("yNetwork") + strerror(errno));
else
perror("yNetwork");
}
this->removePeer(id);
}
else if (readLength == 0)
{
this->getCallback()->onPeerDisconnect(id, NetworkInfo_ConnectionClosed);
this->removePeer(id);
}
else
{
// Setup the BitStream
BitStream data(&buffer[0], readLength);
// Loop until we finished reading
while (data.getByteIndex() < data.getLength())
{
if (!peers[id]->msgCache)
{
// The length of the message
u32 length = data.read<u32>();
// Check wheter the whole package was read
if (length <= ( data.getLength()-data.getByteIndex() ) )
{
BitStream message;
data.copyRawArray<c8>(&message, length);
if(encrypter && encrypter->isValid())
{
encrypter->decrypt(message);
}
message.setByteIndex(0);
u8 msgType = message.read<u8>();
c8* dataStr = message.readRawArray<c8>(message.getLength()-1);
this->getCallback()->onMessageReceived(id, msgType, dataStr, message.getLength()-1);
delete []dataStr;
}
else
{
peers[id]->msgCache = new BitStream(length);
// Append everything to the cache
// We would like to read lenght-5 but we can only read some of it
data.copyRawArray<c8>(peers[id]->msgCache, data.getLength()-data.getByteIndex(), true, false);
}
}
else
{
// Calculate how much we have to read
u32 length = peers[id]->msgCache->getLength() - peers[id]->msgCache->getByteIndex();
// If we STILL didn't receive everything we just read a piece of it again
if (static_cast<u32>(readLength) < length)
length = readLength;
// Append data to the cache :)
data.copyRawArray<c8>(peers[id]->msgCache, length, true, false);
if (peers[id]->msgCache->isAtEnd())
{
if(encrypter && encrypter->isValid())
{
encrypter->decrypt(*peers[id]->msgCache);
}
peers[id]->msgCache->setByteIndex(0);
u8 msgType = peers[id]->msgCache->read<u8>();
c8* dataStr = peers[id]->msgCache->readRawArray<c8>(peers[id]->msgCache->getLength()-1);
// Everything was received!
this->getCallback()->onMessageReceived(id, msgType , dataStr, peers[id]->msgCache->getLength()-1);
// Clean up
delete peers[id]->msgCache;
delete []dataStr;
peers[id]->msgCache = 0;
}
}
}
}
}
Kann es sein dass strerror() einen Crash verursacht? Vielleicht wenn die errno einen unbekannten Wert hat? Das kann ich mir aber irgendwie nicht vorstellen.
gruß,
Halan