Nätverksspel CDX, fryslagg/krash

Permalänk

Nätverksspel CDX, fryslagg/krash

Goddag alla Sweclockare. Jobbar tillsammans med en polare med att skapa ett platformsspel med stöd för multiplayer. Vi har det som projektarbete nu i trean och använder oss av biblioteket CDX tillsammans med tilläggsbiblioteket CDXConnection för att få stöd för kommunikation över internet.

Jag har skrivit kod som ritar upp 4 simpla kuber som man sedan kan välja en av för att spela, jag har även skapat en simpel server som tar emot positionerna för kuberna och skickar ut dem till alla som är uppkopplade mot servern. Det är inget fel på koden och den klarar av att skicka mellan de olika klienterna i cirka 30sekunder. Sedan krashar spelet av någon anledning och du måste avsluta processen via aktivitetshanteraren. Då jag inte lyckas hitta några fel i koden har jag svårt att förstå varför spelet fryser.

Det jag undrar är om ni har några tips på vad som kan få det här problemet att uppstå. Vid behov kan jag bifoga all kod som är skriven men då den är så simpel som den kan bli kan jag inte hitta några fel i den. Allt den gör är att skapa 4 bilder(objekt) och skicka positionerna över internet med TCP/IP protokoll.

EDIT:

SERVER

Deklarering

// alltid med, skärmen och indata DECLARE CDXScreen *Screen; DECLARE CDXInput Input; // referens till skärmytan i minnet, dit man ritar allt DECLARE CDXSurface *BackBuffer; DECLARE CDXConnection *Con; DECLARE char data[256]; DECLARE int node; DECLARE int read; DECLARE int x;

Dold text

Initiering

// skapa skärmen Screen = new CDXScreen; Screen->CreateFullScreen(hWnd, 640, 480, 16); // rensa back- och frontbuffer Screen->GetBack()->Fill(0); Screen->GetFront()->Fill(0); // skapa en referens till backbuffer (för enklare användning senare, rita på denna) BackBuffer = Screen->GetBack(); Con = new CDXConnection(); Con->CreateHost(); Con->Listen(4404); x=0; data[256] // // Här ska vår kod för att skapa objekt in // SetRect(&Window, 0, 0, 640, 480);

Dold text

Active (den del som körs om och om igen medans programmet är igång ^^)

if(Con->isDataReady()){ Con->getData(node, data, sizeof(data), read); //cout<<Node<<endl<<endl; //cout<<Con->getNumConnections()<<endl; //cout<<Data<<endl; //x++; } //if(x>=90){ Con->sendData(NODE_ALL, data, sizeof(data)); //x=0; //}

Dold text
Dold text

Klient

Deklarering

// alltid med, skärmen och indata DECLARE CDXScreen *Screen; DECLARE CDXInput Input; // referens till skärmytan i minnet, dit man ritar allt DECLARE CDXSurface *BackBuffer; DECLARE CDXSurface *Grund; DECLARE CDXSprite *Player_1; DECLARE CDXSprite *Player_2; DECLARE CDXSprite *Player_3; DECLARE CDXSprite *Player_4; DECLARE CDXSprite *Local_player; DECLARE CDXConnection *Con; DECLARE bool meny; DECLARE bool playing; DECLARE int player; DECLARE char data[256]; DECLARE int read; DECLARE int node; void Encode_Int(int start, int message); int Decode_Int(int start);

Dold text

Initiering

// skapa skärmen Screen = new CDXScreen; Screen->CreateFullScreen(hWnd, 1280, 960, 16); // rensa back- och frontbuffer Screen->GetBack()->Fill(0); Screen->GetFront()->Fill(0); // skapa en referens till backbuffer (för enklare användning senare, rita på denna) BackBuffer = Screen->GetBack(); Grund = new CDXSurface(); Grund->Create(Screen, "data/grund.bmp"); Player_1 = new CDXSprite(); Player_1->Create(Screen, "data/red.bmp", 34, 66, 1); Player_1->SetColorKey(); Player_1->SetPos(320,240); Player_2 = new CDXSprite(); Player_2->Create(Screen, "data/blue.bmp", 34, 66, 1); Player_2->SetColorKey(); Player_2->SetPos(960,240); Player_3 = new CDXSprite(); Player_3->Create(Screen, "data/yellow.bmp", 34, 66, 1); Player_3->SetColorKey(); Player_3->SetPos(320,720); Player_4 = new CDXSprite(); Player_4->Create(Screen, "data/green.bmp", 34, 66, 1); Player_4->SetColorKey(); Player_4->SetPos(960,720); Con = new CDXConnection(); Con->CreateClient(); Con->Connect("localhost",4404); //213.114.77.81 meny=true; playing=false; player=0; data[256]=new char;

Dold text

Active

Input

Input.Update(); if(Input.GetKeyState(CDXKEY_T) && meny) { Local_player=Player_1; player=1; meny=false; } if(Input.GetKeyState(CDXKEY_Y) && meny) { Local_player=Player_2; player=2; meny=false; } if(Input.GetKeyState(CDXKEY_U) && meny) { Local_player=Player_3; player=3; meny=false; } if(Input.GetKeyState(CDXKEY_I) && meny) { Local_player=Player_4; player=4; meny=false; } if(Input.GetKeyState(CDXKEY_P)){ playing=true; } if(Input.GetKeyState(CDXKEY_W) && !meny) { // Upp if(Local_player->GetVelY() != -2) Local_player->SetVelY(-2); else Local_player->SetPosY(Local_player->GetPosY()+Local_player->GetVelY()); } if(Input.GetKeyState(CDXKEY_S) && !meny) { // Ner if(Local_player->GetVelY() != 2) Local_player->SetVelY(2); else Local_player->SetPosY(Local_player->GetPosY()+Local_player->GetVelY()); } if(Input.GetKeyState(CDXKEY_A) && !meny) { // Vänster if(Local_player->GetVelX() != -2) Local_player->SetVelX(-2); else Local_player->SetPosX(Local_player->GetPosX()+Local_player->GetVelX()); } if(Input.GetKeyState(CDXKEY_D) && !meny) { // Höger if(Local_player->GetVelX() != 2) Local_player->SetVelX(2); else Local_player->SetPosX(Local_player->GetPosX()+Local_player->GetVelX()); }

Dold text

Uppdatering

if(Con->isDataReady()){ Con->getData(node, data, sizeof(data), read); switch(player){ case 0: break; case 1: Player_2->SetPos(Decode_Int(20),Decode_Int(24)); Player_3->SetPos(Decode_Int(40),Decode_Int(44)); Player_4->SetPos(Decode_Int(60),Decode_Int(64)); break; case 2: Player_1->SetPos(Decode_Int(0),Decode_Int(4)); Player_3->SetPos(Decode_Int(40),Decode_Int(44)); Player_4->SetPos(Decode_Int(60),Decode_Int(64)); break; case 3: Player_1->SetPos(Decode_Int(0),Decode_Int(4)); Player_2->SetPos(Decode_Int(20),Decode_Int(24)); Player_4->SetPos(Decode_Int(60),Decode_Int(64)); break; case 4: Player_1->SetPos(Decode_Int(0),Decode_Int(4)); Player_2->SetPos(Decode_Int(20),Decode_Int(24)); Player_3->SetPos(Decode_Int(40),Decode_Int(44)); break; } } if(playing){ switch(player){ case 0: break; case 1: Encode_Int(0, Local_player->GetPosX()); Encode_Int(4, Local_player->GetPosY()); break; case 2: Encode_Int(20, Local_player->GetPosX()); Encode_Int(24, Local_player->GetPosY()); break; case 3: Encode_Int(40, Local_player->GetPosX()); Encode_Int(44, Local_player->GetPosY()); break; case 4: Encode_Int(60, Local_player->GetPosX()); Encode_Int(64, Local_player->GetPosY()); break; } //Encode_Int(0, Local_player->GetPosX()); //Encode_Int(4, Local_player->GetPosY()); //if(Con->StillConnected()) Con->sendData(NODE_SERVER, data, sizeof(data)); }

Dold text

Uppritning och de två funktionerna för char->int och vice versa

void Draw(void) { // rita allting här, till BackBuffer (eller Screen->GetBack()) Grund->DrawBlk(BackBuffer, 0, 0); Player_2->Draw(BackBuffer, 0, 0, CDXBLT_TRANS); Player_3->Draw(BackBuffer, 0, 0, CDXBLT_TRANS); Player_4->Draw(BackBuffer, 0, 0, CDXBLT_TRANS); Player_1->Draw(BackBuffer, 0, 0, CDXBLT_TRANS); // flippa så att skärmytan i minnet (backbuffer) visas Screen->Flip(TRUE,TRUE,TRUE); } void Encode_Int(int start, int message){ data[start] = message & 0xFF; data[start+1] = (message >> 8) & 0xFF; data[start+2] = (message >> 16) & 0xFF; data[start+3] = (message >> 24) & 0xFF; } int Decode_Int(int start){ return (int)((UCHAR)data[start]+((UCHAR)*data[start+1] << 8)+((UCHAR)data[start+2] << 16)+((UCHAR)data[start+3] << 24)); }

Dold text

Dold text
Dold text
Lade till all kod
Permalänk
Medlem

Det är alltid fel på koden om nåt går fel
Pasta koden.

Visa signatur

Corsair 16GB (4x4096MB) CL9 1600Mhz | Asus P8Z77-V PRO |
Samsung SSD Basic 830-Series 256GB | Intel Core i7 3770K 3,5Ghz |
Asus Xonar Essence STX | Noctua NH-U9B SE2 | Antec Performance One P280 | Corsair HX 850W 80+ Gold Modulär | MSI GTX 770

Permalänk
Medlem

Utan att se koden är det svårt att säga, men rent spontant kan jag tänka mig två saker om det fungerar ett tag och sedan fryser:
1) Du allokerar mer och mer minne i spelet tills det tar slut. Om du kör C/C++ (eller annat språk med manuell minneshantering) så måste du lägga in free/delete för att frigöra minne efter att du är färdig med det. Om du kör C#/Java (eller annat språk med skräpuppsamling) så är det möjligt att du har kvar länkar till objekt som inte längre används.
2) Deadlock. Någonstans har du parallella processer som är beroende av varandra. Troligen handlar det om flera trådar, där den ena ligger och väntar på den andra, som av någon anledning blokerats.

Permalänk
Medlem

Använd en debugger.

Visa signatur

Intel Core i7-3770K | NVIDIA Geforce GTX 980 | 16 GB DDR3 | DELL P2415Q | DELL U2711 | DELL U2410

Permalänk
Skrivet av NoPaiN^:

Det är alltid fel på koden om nåt går fel
Pasta koden.

Koden uppe i första inlägget, om det behövs så kan jag ladda upp hela projektet i en rar fil så ni kan ladda ner och prova själva.

Skrivet av Thomas H:

Utan att se koden är det svårt att säga, men rent spontant kan jag tänka mig två saker om det fungerar ett tag och sedan fryser:
1) Du allokerar mer och mer minne i spelet tills det tar slut. Om du kör C/C++ (eller annat språk med manuell minneshantering) så måste du lägga in free/delete för att frigöra minne efter att du är färdig med det. Om du kör C#/Java (eller annat språk med skräpuppsamling) så är det möjligt att du har kvar länkar till objekt som inte längre används.
2) Deadlock. Någonstans har du parallella processer som är beroende av varandra. Troligen handlar det om flera trådar, där den ena ligger och väntar på den andra, som av någon anledning blokerats.

1)Har provat att använda pekare för att spara på minneshantering men märkte ingen skillnad, har du några fler tips på hur jag skulle kunna spara in på minne så vore jag jäkligt nöjd då det kan komma att behövas senare.

2)Vad jag vet så är koden lite dum och kör bara en tråd runt runt så det borde inte vara några problem med att de låser varandra kan dock uppfattat det fel.

Skrivet av MagnusL:

Använd en debugger.

Måste prova att göra det så fort jag får tid över. Hur fungerar en sån? Fick höra att om man har tur så kan den berätta problemet i klartext annars spottar han debuggern ur sig en lång lustig felkod :/

Permalänk
Medlem

Finns lite småsaker ni bör tänka på i koden, men inget som jag ser skullle göra att det krasha för er.
Är det klienten eller servern som slutar svarar?

Lägg upp hela koden, har ni ingen loop etc?

Visa signatur

Corsair 16GB (4x4096MB) CL9 1600Mhz | Asus P8Z77-V PRO |
Samsung SSD Basic 830-Series 256GB | Intel Core i7 3770K 3,5Ghz |
Asus Xonar Essence STX | Noctua NH-U9B SE2 | Antec Performance One P280 | Corsair HX 850W 80+ Gold Modulär | MSI GTX 770

Permalänk
Medlem
Skrivet av Joakim_lid:

1)Har provat att använda pekare för att spara på minneshantering men märkte ingen skillnad, har du några fler tips på hur jag skulle kunna spara in på minne så vore jag jäkligt nöjd då det kan komma att behövas senare.

Att använda pekare i sig gör ingen skillnad (eller nja, du allokerar ju en pekare som tar upp 4-8 byte), det som spelar roll är ju om du använder malloc/new för att allokera dynamiskt minne och sedan inte har en matchande free/delete för att frigöra minnet när du är färdig med det. Om man inte frigör dynamiskt minne så riskerar man att programmet läcker minne, alltså att mer och mer minne reserveras trots att det inte används. Om du kommer från språk med automatiskt minneshantering (e.g. Java/C#) så kan det vara lätt att glömma.

Att optimera för minnesåtgång är något annat. Allmänt finns det inte så mycket att säga. Använd int8_t och liknande istället för int om du inte behöver 2^32 värden. Om du inte håller på med något speciellt lär du dock inte behöva tänka så mycket på det. Datorer idag har mer än nog minne för det mesta, så vänta med optimering tills du vet att det behövs.

Citat:

2)Vad jag vet så är koden lite dum och kör bara en tråd runt runt så det borde inte vara några problem med att de låser varandra kan dock uppfattat det fel.

Kollade din kod lite snabbt, såg ingenting uppenbart som tyder på deadlock. Dock är det ju inte hela koden du skickat, så svårt att säga på rak arm. Verkar inte finnas några loopar, och fryser programmet så är ju det något att kolla på. Det är inte så att ni har funktioner som anropar varandra så att ni får en sorts oändlig rekursion som hela tiden ökar minnesåtgången?

Permalänk
Skrivet av NoPaiN^:

Finns lite småsaker ni bör tänka på i koden, men inget som jag ser skullle göra att det krasha för er.
Är det klienten eller servern som slutar svarar?

Lägg upp hela koden, har ni ingen loop etc?

Jo vi har loop men ville inte lägga in massa kod som är i orginal utförande som den följde med biblioteket. Men här kommer all kod utan några undantag(Skickar inte med bilderna på objekten då det bara är enfärgade kuber)

Servern: http://puu.sh/1xsfK

Klienten: http://puu.sh/1xshJ

EDIT: Glömde ju säga att det är i C++ jag jobbar och kompilatorn som används är Bloodshed DevCPP

Permalänk
Medlem
Skrivet av Joakim_lid:

Jo vi har loop men ville inte lägga in massa kod som är i orginal utförande som den följde med biblioteket. Men här kommer all kod utan några undantag(Skickar inte med bilderna på objekten då det bara är enfärgade kuber)

Servern: http://puu.sh/1xsfK

Klienten: http://puu.sh/1xshJ

EDIT: Glömde ju säga att det är i C++ jag jobbar och kompilatorn som används är Bloodshed DevCPP

Du menar att BLOODSHED är det IDE du arbetar i?

Visa signatur

Ryzen 5600X | MSI Tomahawk | GTX 3070

Permalänk
Skrivet av Thomas H:

Kollade din kod lite snabbt, såg ingenting uppenbart som tyder på deadlock. Dock är det ju inte hela koden du skickat, så svårt att säga på rak arm. Verkar inte finnas några loopar, och fryser programmet så är ju det något att kolla på. Det är inte så att ni har funktioner som anropar varandra så att ni får en sorts oändlig rekursion som hela tiden ökar minnesåtgången?

Har laddat upp hela koden nu och postat den i ett inlägg längre upp. Skulle bli sjukt glad om du orkade ta en titt på dem om det säger något mer än det jag redan skrivit.

Skrivet av MagnusL:

Använd en debugger.

Provade att köra en debugger dock krashade den och gav mig inga svar. Ska prova att köra debugger igen på en annan dator bara för att kolla. Kan man ladda ner någon annan debugger och prova med ? Jag provade med något som heter Insight om jag inte läste fel bland de program jag körde.

Permalänk
Medlem
Skrivet av Joakim_lid:

Har laddat upp hela koden nu och postat den i ett inlägg längre upp. Skulle bli sjukt glad om du orkade ta en titt på dem om det säger något mer än det jag redan skrivit.

Provade att köra en debugger dock krashade den och gav mig inga svar. Ska prova att köra debugger igen på en annan dator bara för att kolla. Kan man ladda ner någon annan debugger och prova med ? Jag provade med något som heter Insight om jag inte läste fel bland de program jag körde.

Finns många olika sätt att debuga kod, stegdebug och utskrifter är mycket simpelt och fungerar ofta.
Kör alltid i debugläge och inte release om du ska kolla fel, sätt din compiler för att hantera warnings lvl 4 och errors.

Det du kan försöka tänka på i detta fallet, är det klienten eller är det servern som Krashar?
Var och när inträffar Krashen oftast?
När du tror veta var och när i koden det krashar, minimera koden/kommentera bort, för att utesluta saker.
Sen stegdebuga och gör utskrifter och följ din kod.
Kan du inte hitta var i koden och när det inträffar.
Stegdebuga från början då, förmodligen ser du rätt snabbt vad det är som är galet.
Kanske minneshanteringen ökar enormt?
Alternativt kan du göra en egen klass som skriver ut till en fil etc.

Visa signatur

Corsair 16GB (4x4096MB) CL9 1600Mhz | Asus P8Z77-V PRO |
Samsung SSD Basic 830-Series 256GB | Intel Core i7 3770K 3,5Ghz |
Asus Xonar Essence STX | Noctua NH-U9B SE2 | Antec Performance One P280 | Corsair HX 850W 80+ Gold Modulär | MSI GTX 770

Permalänk
Skrivet av NoPaiN^:

Finns många olika sätt att debuga kod, stegdebug och utskrifter är mycket simpelt och fungerar ofta.
Kör alltid i debugläge och inte release om du ska kolla fel, sätt din compiler för att hantera warnings lvl 4 och errors.

Det du kan försöka tänka på i detta fallet, är det klienten eller är det servern som Krashar?
Var och när inträffar Krashen oftast?
När du tror veta var och när i koden det krashar, minimera koden/kommentera bort, för att utesluta saker.
Sen stegdebuga och gör utskrifter och följ din kod.
Kan du inte hitta var i koden och när det inträffar.
Stegdebuga från början då, förmodligen ser du rätt snabbt vad det är som är galet.
Kanske minneshanteringen ökar enormt?
Alternativt kan du göra en egen klass som skriver ut till en fil etc.

1. Har nästan helt säkert kommit fram till att det är klienten som krashar, eftersom att det bara sker medans klienten försöker skicka/ta emot data. (Om man startar en klient utan server att skicka till så uppstår inga krasher. ***

2. Krashen sker enbart några få sekunder efter att klienten har börjat skicka data till servern. Skulle kunna vara något med att minnet överfylls med data.

3. Jag har innan jag skapat tråden kommenterat bort och flera gånger provat mig fram till att det är när skickandet + mottagandet av data sker som krashen inträffar.

4. Har försökt göra stegdebugging men får inte debugger verktyget att fungera på något vettigt sätt hur jag än provar. Antingen krashar programmet och programmet + blodshed(kompilator + debugger) låser sig, om det inte krashar går det inte att gå med steg genom det som jag provat att göra i mindre konsoll-program.

*** Jag vet ju enbart att det är något fel med skickandet av data till och från server/klient. Problemet är att jag inte vet hur man ska kunna se vilken av dem som krashar.

Permalänk
Medlem

Hur gör du när du skickar paket va nätverket, framebaserat, bara när det skett en förändring, i varje loopiteration?
Har du öppnat taskmanager eller dylikt och kollat minneshanteringen, om du kollar på din klient så kanske minnet ökar avsevärt.

Visa signatur

Corsair 16GB (4x4096MB) CL9 1600Mhz | Asus P8Z77-V PRO |
Samsung SSD Basic 830-Series 256GB | Intel Core i7 3770K 3,5Ghz |
Asus Xonar Essence STX | Noctua NH-U9B SE2 | Antec Performance One P280 | Corsair HX 850W 80+ Gold Modulär | MSI GTX 770

Permalänk
Skrivet av NoPaiN^:

Hur gör du när du skickar paket via nätverket, framebaserat, bara när det skett en förändring, i varje loopiteration?
Har du öppnat taskmanager eller dylikt och kollat minneshanteringen, om du kollar på din klient så kanske minnet ökar avsevärt.

Jag skickar paket varje loopiteration (och kollar om det finns data att ta emot på samma gång).

Har försökt att öpnna taskmanager och kolla. Problemet är att medans programmet inte skickar data så ligger minnesanvändningen på en rimlig nivå och när jag startar data skickandet krashar programmet så fort att det man inte hinner kolla i taskmanager.

Permalänk
Medlem

Prova bara skicka en gång då, och se vad som händer, gör en utskrift på servern och klienten.
Typ när en knapp är nertryckt skickar du ett paket med pos eller dylikt, följd koden och kolla minnes hanteringen etc.
Låter ju mer som att du får fel index i en array eller att nåt är null.

Visa signatur

Corsair 16GB (4x4096MB) CL9 1600Mhz | Asus P8Z77-V PRO |
Samsung SSD Basic 830-Series 256GB | Intel Core i7 3770K 3,5Ghz |
Asus Xonar Essence STX | Noctua NH-U9B SE2 | Antec Performance One P280 | Corsair HX 850W 80+ Gold Modulär | MSI GTX 770