Gameserver

Status
Niet open voor verdere reacties.

erikiej1

Gebruiker
Lid geworden
29 apr 2008
Berichten
138
Ik heb een online game en een bijbehorende server geprogrammeerd in C++.
Het spel is echter ontzettend traag, terwijl ik de graphics heel simpel heb gelaten,
dus het moet aan de verbinding met de server liggen.
Ik draai de server gewoon op mijn eigen computer.
Wordt het spel dan sneller als ik een dedicated server koop/huur en m'n gameserver daarop zet?
Ik heb daar geen ervaring mee, dus kan iemand mij een beetje voorlichten?
Zowel het spel als de server hebben windows socket 2 nodig.

Groet van Erik.
 
Hoe snel is de server als je die op je pc draait waarop ook de client speelt die je connect op ip adres 127.0.0.1?

Als dat ook traag is ligt het niet aan je netwerk
 
Nou. Als één client verbindt, merk je eigenlijk niets van de verbinding met de server.
Het zijn alleen de andere clienten die heel sloom reageren.
 
zelfde probleem gehad...
Wat je kan probeeren (als je dit nog niet hebt gedaan) is een socket server maken
In plaats van 1 HOOFD server maak je de persoonen die spelen als server..
bv"
SPELER 1: Server is SPELER 2 en SPELER 3
SPELER 2 S1 en S3
S3 = S1 en S2

Zo laat je de ander computers meer doen
met deze methode heb je ook niets van timers nodig of interval omdat deze luistert naar het minste dat verranderd op de server..

Zorg wel dat je een niet in beslag genomen TCP port gebruikt :thumb:
 
Zelfde principe

Effe een duidelijkheid op bovenstaande vraag:

Dit is een voorbeeld van Remote shutdown (maar zelfde principe met wat aanpassingen
Elk spel zou een server en een client moeten hebben om gegevens te verzenden en ophaalen
aangezien ik niet weet wat het spel is of wat het doet zou dit mischien hetzelfde kunnen zijn wat je al hebt..

SERVER:

vb
PHP:
  Dim trSendMessage As Thread

    Sub SendMessage()
        Dim host As String = txtClientIP.Text
        Dim port As Integer = 63000
        Try
            Dim tcpCli As New TcpClient(host, port)
            Dim ns As NetworkStream = tcpCli.GetStream

            ' Send data to the server.
            Dim sw As New StreamWriter(ns)
            If rbShutdown.Checked = True Then
                sw.WriteLine("###SHUTDOWN###")
            End If
            If rbReboot.Checked = True Then
                sw.WriteLine("###REBOOT###")
            End If
            If rbLogOff.Checked = True Then
                sw.WriteLine("###LOGOFF###")
            End If
            If rbNothing.Checked = True Then
                sw.WriteLine("to")
            End If
            sw.Flush()

            ' Receive and display data.
            Dim sr As New StreamReader(ns)
            Dim result As String = sr.ReadLine()
            If result = "###OK###" Then
                MsgBox("Operation Performed!!!", MsgBoxStyle.Information, "Accepted by client")
            End If
            'MsgBox(result)
            sr.Close()
            sw.Close()
            ns.Close()
        Catch ex As Exception
            MsgBox(ex.Message)
        End Try
    End Sub
    Private Sub btnExit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnExit.Click
        End
    End Sub

    Private Sub btnOK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOK.Click
        If Trim(txtClientIP.Text) = "" Then
            MsgBox("Please enter Client IP Address!!!", MsgBoxStyle.Information, "IP Address???")
            txtClientIP.Focus()
            Exit Sub
        End If
        If rbNothing.Checked = False Then
            trSendMessage = New Thread(AddressOf SendMessage)
            trSendMessage.Start()
        End If
    End Sub
    Dim ipAddress As IPAddress = Dns.Resolve(Dns.GetHostName()).AddressList(0)

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        lblMYIP.Text = ipAddress.ToString
    End Sub

C++
PHP:
Thread trSendMessage;
Sub
    
    private IPAddress ipAddress = Dns.Resolve(Dns.GetHostName()).AddressList(0);
    
    void SendMessage() {
        string host = txtClientIP.Text;
        int port = 63000;
        try {
            TcpClient tcpCli = new TcpClient(host, port);
            NetworkStream ns = tcpCli.GetStream;
            //  Send data to the server.
            StreamWriter sw = new StreamWriter(ns);
            if ((rbShutdown.Checked == true)) {
                sw.WriteLine("###SHUTDOWN###");
            }
            if ((rbReboot.Checked == true)) {
                sw.WriteLine("###REBOOT###");
            }
            if ((rbLogOff.Checked == true)) {
                sw.WriteLine("###LOGOFF###");
            }
            if ((rbNothing.Checked == true)) {
                sw.WriteLine("to");
            }
            sw.Flush();
            //  Receive and display data.
            StreamReader sr = new StreamReader(ns);
            string result = sr.ReadLine();
            if ((result == "###OK###")) {
                MsgBox("Operation Performed!!!", MsgBoxStyle.Information, "Accepted by client");
            }
            // MsgBox(result)
            sr.Close();
            sw.Close();
            ns.Close();
        }
        catch (Exception ex) {
            MsgBox(ex.Message);
        }
    }
    
    private void btnExit_Click(object sender, System.EventArgs e) {
    }
    
    private void btnOK_Click(object sender, System.EventArgs e) {
        if ((txtClientIP.Text.Trim() == "")) {
            MsgBox("Please enter Client IP Address!!!", MsgBoxStyle.Information, "IP Address???");
            txtClientIP.Focus();
            return;
        }
        if ((rbNothing.Checked == false)) {
            trSendMessage = new Thread(new System.EventHandler(this.SendMessage));
            trSendMessage.Start();
        }
    }
    
    private void Form1_Load(object sender, System.EventArgs e) {
        lblMYIP.Text = ipAddress.ToString;
    }

CLIENT:
vb
PHP:
 Dim trlisten As Thread
    Dim trShutdown As Thread
    Dim trReboot As Thread
    Dim trLogOff As Thread
    Sub shutdown()
        Dim t As Single
        Dim objWMIService, objComputer As Object
        'Now get some privileges
        objWMIService = GetObject("Winmgmts:{impersonationLevel=impersonate,(Debug,Shutdown)}")
        For Each objComputer In objWMIService.InstancesOf("Win32_OperatingSystem")

            t = objComputer.Win32Shutdown(8 + 4, 0)

            If t <> 0 Then
                'Error occurred!!!
            Else
                'Shutdown your system
            End If
        Next
    End Sub
    Sub reboot()
        Dim t As Single
        Dim objWMIService, objComputer As Object
        'Now get some privileges
        objWMIService = GetObject("Winmgmts:{impersonationLevel=impersonate,(Debug,Shutdown)}")
        For Each objComputer In objWMIService.InstancesOf("Win32_OperatingSystem")

            t = objComputer.Win32Shutdown(2 + 4, 0)

            If t <> 0 Then
                'Error occurred!!!
            Else
                'Reboot your system
            End If
        Next
    End Sub
    Sub logoff()
        Dim t As Single
        Dim objWMIService, objComputer As Object
        'Now get some privileges
        objWMIService = GetObject("Winmgmts:{impersonationLevel=impersonate,(Debug,Shutdown)}")
        For Each objComputer In objWMIService.InstancesOf("Win32_OperatingSystem")

            t = objComputer.Win32Shutdown(0, 0)

            If t <> 0 Then
                'Error occurred!!!
            Else
                'LogOff your system
            End If
        Next
    End Sub
    Sub ListenToServer()
        'Try

        Dim LISTENING As Boolean
        Dim localhostAddress As IPAddress = ipAddress.Parse(ipAddress.ToString)
        Dim port As Integer = 63000      '' PORT ADDRESS
        ''''''''''' making socket tcpList ''''''''''''''''
        Dim tcpList As New TcpListener(localhostAddress, port)
        Try
            tcpList.Start()
            LISTENING = True

            Do While LISTENING

                Do While tcpList.Pending = False And LISTENING = True
                    ' Yield the CPU for a while.
                    Thread.Sleep(10)
                Loop
                If Not LISTENING Then Exit Do

                Dim tcpCli As TcpClient = tcpList.AcceptTcpClient()
                'ListBox1.Items.Add("Data from " & "128.10.20.63")
                Dim ns As NetworkStream = tcpCli.GetStream
                Dim sr As New StreamReader(ns)
                ''''''''' get data from client '''''''''''''''
                Dim receivedData As String = sr.ReadLine()
                If receivedData = "###SHUTDOWN###" Then
                    trShutdown = New Thread(AddressOf shutdown)
                    trShutdown.Start()
                End If
                If receivedData = "###REBOOT###" Then
                    trReboot = New Thread(AddressOf reboot)
                    trReboot.Start()
                End If
                If receivedData = "###LOGOFF###" Then
                    trLogOff = New Thread(AddressOf logoff)
                    trLogOff.Start()
                End If

                Dim returnedData As String = "###OK###" '& " From Server"
                Dim sw As New StreamWriter(ns)
                sw.WriteLine(returnedData)
                sw.Flush()
                sr.Close()
                sw.Close()
                ns.Close()
                tcpCli.Close()
            Loop
            tcpList.Stop()
        Catch ex As Exception
            'error
            LISTENING = False
        End Try
    End Sub
    Dim ipAddress As IPAddress = Dns.Resolve(Dns.GetHostName()).AddressList(0)

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        NotifyIcon1.Icon = Me.Icon
        lblMYIP.Text = ipAddress.ToString
        trlisten = New Thread(AddressOf ListenToServer)
        trlisten.Start()
    End Sub

    Private Sub btnClose_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnClose.Click
        NotifyIcon1.Visible = False
        End
    End Sub

    Private Sub btnHide_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnHide.Click
        NotifyIcon1.Visible = True
        Me.Hide()
    End Sub


    Private Sub NotifyIcon1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles NotifyIcon1.Click
        Me.Show()
    End Sub

c++
PHP:
Thread trlisten;
Thread trShutdown;
Thread trReboot;
Thread trLogOff;
Sub
    
    private IPAddress ipAddress = Dns.Resolve(Dns.GetHostName()).AddressList(0);
    
    void shutdown() {
        float t;
        object objWMIService;
        object objComputer;
        // Now get some privileges
        objWMIService = GetObject("Winmgmts:{impersonationLevel=impersonate,(Debug,Shutdown)}");
        foreach (objComputer in objWMIService.InstancesOf("Win32_OperatingSystem")) {
            t = objComputer.Win32Shutdown((8 + 4), 0);
            if ((t != 0)) {
                // Error occurred!!!
            }
            else {
                // Shutdown your system
            }
        }
    }
    
    void reboot() {
        float t;
        object objWMIService;
        object objComputer;
        // Now get some privileges
        objWMIService = GetObject("Winmgmts:{impersonationLevel=impersonate,(Debug,Shutdown)}");
        foreach (objComputer in objWMIService.InstancesOf("Win32_OperatingSystem")) {
            t = objComputer.Win32Shutdown((2 + 4), 0);
            if ((t != 0)) {
                // Error occurred!!!
            }
            else {
                // Reboot your system
            }
        }
    }
    
    void logoff() {
        float t;
        object objWMIService;
        object objComputer;
        // Now get some privileges
        objWMIService = GetObject("Winmgmts:{impersonationLevel=impersonate,(Debug,Shutdown)}");
        foreach (objComputer in objWMIService.InstancesOf("Win32_OperatingSystem")) {
            t = objComputer.Win32Shutdown(0, 0);
            if ((t != 0)) {
                // Error occurred!!!
            }
            else {
                // LogOff your system
            }
        }
    }
    
    void ListenToServer() {
        // Try
        bool LISTENING;
        IPAddress localhostAddress = ipAddress.Parse(ipAddress.ToString);
        int port = 63000;
        // ' PORT ADDRESS
        // '''''''''' making socket tcpList ''''''''''''''''
        TcpListener tcpList = new TcpListener(localhostAddress, port);
        try {
            tcpList.Start();
            LISTENING = true;
            while (LISTENING) {
                while (((tcpList.Pending == false) 
                            && (LISTENING == true))) {
                    Thread.Sleep(10);
                }
                if (!LISTENING) {
                    break; //Warning!!! Review that break works as 'Exit Do' as it could be in a nested instruction like switch
                }
                TcpClient tcpCli = tcpList.AcceptTcpClient();
                // ListBox1.Items.Add("Data from " & "128.10.20.63")
                NetworkStream ns = tcpCli.GetStream;
                StreamReader sr = new StreamReader(ns);
                // '''''''' get data from client '''''''''''''''
                string receivedData = sr.ReadLine();
                if ((receivedData == "###SHUTDOWN###")) {
                    trShutdown = new Thread(new System.EventHandler(this.shutdown));
                    trShutdown.Start();
                }
                if ((receivedData == "###REBOOT###")) {
                    trReboot = new Thread(new System.EventHandler(this.reboot));
                    trReboot.Start();
                }
                if ((receivedData == "###LOGOFF###")) {
                    trLogOff = new Thread(new System.EventHandler(this.logoff));
                    trLogOff.Start();
                }
                string returnedData = "###OK###";
                StreamWriter sw = new StreamWriter(ns);
                sw.WriteLine(returnedData);
                sw.Flush();
                sr.Close();
                sw.Close();
                ns.Close();
                tcpCli.Close();
            }
            tcpList.Stop();
        }
        catch (Exception ex) {
            // error
            LISTENING = false;
        }
    }
    
    private void Form1_Load(object sender, System.EventArgs e) {
        NotifyIcon1.Icon = this.Icon;
        lblMYIP.Text = ipAddress.ToString;
        trlisten = new Thread(new System.EventHandler(this.ListenToServer));
        trlisten.Start();
    }
    
    private void btnClose_Click(object sender, System.EventArgs e) {
        NotifyIcon1.Visible = false;
    }
    
    private void btnHide_Click(object sender, System.EventArgs e) {
        NotifyIcon1.Visible = true;
        this.Hide();
    }
    
    private void NotifyIcon1_Click(object sender, System.EventArgs e) {
        this.Show();
    }
 
Laatst bewerkt:
voor elke client zou de server een eigen tread moeten hebben voor het ontvangen van de berichten en het uitvoeren er van. of je maakt gebruik van 2 treads eentje voor het ontvangen en eentje voor het uitvoeren van de berichten. en zorg er voor dat de berichten zo klein mogelijk zijn bv maar een hex waarde.
EDIT: hoe stuur jij de data naar de clients, zodra er iets naar de server is gestuurd het direct doorsturen naar de client of bv na een turn all data. en maak je gebruik van tcp of udp?
 
Laatst bewerkt:
Hm.
Ik heb voor elke client één thread.
Elke keer als de server gegevens van een client krijgt, zendt hij alles terug.
Dat wil zeggen, 300 complete objecten met zeer veel integers en characters.
(Sommige objecten zijn echter leeg, ik weet niet of dat dan ook extra tijd kost om te verzenden)
Ik heb geen idee hoe ik mijn complete classes met alle gegevens van één speler terug kan brengen op één hex.

Code:
class Compressed_Player{                                           
      private:
         int PosX;                                            
         int PosY;                                                 
         int Action;                                              
         int Health;
         int Weapon;
         bool Active;                                              
         bool Talking;  
         bool Attacking;
         int Attack_X;
         int Attack_Y; 
         int Puke_Dir;                                       
      public:
         char Username[USERNAME_LENGTH];
         char Charactername[CHARACTERNAME_LENGTH];
         char Message [MESSAGE_LENGTH];  

         // nog wat functies, maar die geven geen extra bytes, toch?
};

Ik gebruik TCP.
 
Laatst bewerkt:
Gebruik sowieso zoveel mogelijk UDP ipv tcp verkeer,
TCP genereerd veel meer overhead wat je niet nodig hebt,
 
Ik heb geen flauw idee wat overhead is.
Ik heb nog nooit met UDP gewerkt, wat is het verschil met TCP.
Of is het enige verschil dat ik de sockets van UDP type moet maken.
(en m'n router port niet TCP forwarden, maar UDP)
 
TCP heeft foutafhandeling. dus als een pakketje van a naar b gaat meld b terug aan a dat het pakketje er is en goed is aangekomen. (erg simpel uitgelegd)

UDP heeft dat niet dus kan sneller door blijven zenden wat bij bijvoorbeeld shooter games veel gebruikt word.

Om snelheid in games (bij shooters) te houden boeit het niet zo dat er een pakketje kwijtraakt omdat de 8 pakketjes daarna die info ook wel hebben.
 
Ok.
Dat snap ik nu, dankjewel.
Maar ik weet nu nog niet hoe je UDP gebruikt.
Kun je dat misschien uitleggen of verwijzen naar een goede tutorial (ik ben zeer bekend met winsock, dus als je daar een van hebt zou dat handig zijn)

PS: Helpmij is geweldig; je hebt ontzettend snel reacties op je vraag (:
 
Ik waardeer je inzet, maar dat is geen C++...

er bestaan zeker wel vertaal programmas : :D http://www.carlosag.net/Tools/CodeTranslator/
"Heb de code op vorige vraag bijgevoegd"

Daarbij was het vooral bedoeld als voorbeeld

heb ook een probleem opgemerkt in je beredeneering..
je wilt dus via 1 server werken...
http://www.gamedev.net/community/forums/topic.asp?topic_id=455949
Bovenstaande site legt uit hoe je Multi-TCP clients kan gebruiken
want TCP is even goed als UDP als je een port kiest die niet gebruikt/gebruikt is.
Je kan je programma laaten checken op welke ports er word geluistert :

GA NAAR CMD < RUN < CMD < type: netstat -an
 
Laatst bewerkt:
want TCP is even goed als UDP als je een port kiest die niet gebruikt/gebruikt is.

Dat is een drogreden, want in beide gevallen heb je gewoon een vrije poort nodig. Ellasar geeft toch duidelijk aan wat het verschil is tussen de twee protocollen, waarom dan zo eigenwijs zijn :p


@TS:
Je stuurt nu een hoop data naar de clients toe, welke allemaal geupload moeten worden vanaf jouw internetverbinding. Of een gehoste game-server sneller is hangt dus voornamelijk af van jouw internetverbinding. Maar in de meeste gevallen is een gehoste game-server wel sneller, want de meeste ISP's leveren niet zo'n hoge uploadsnelheid (hoogste dat ik hier kan nemen is bijvoorbeeld 10 Mbit).
 
CoD_NL; Je stuurt nu een hoop data naar de clients toe zei:
Is mischien juist maar dan heb je de kans dat je gegevens onderschept worden,...
Stel nu dat je een computer als server gebruikt (PCGAME) en 3 spelers

SP1 stuurt gegeven naar PCGAME zodat die het naar SP2 en SP3 stuurt
dit kan fout lopen als :

SP1 en SP2 sturen tegelijk gegevens (+-tijd die nodig is om te coderen en te verzenden) naar PCGAME (de snelste wint) naar SP2 en SP3 (de gegevens van SP2 worden niet ontvangen

Natuurlijk zou je dit kunnen vermijden door alle gegevens per speler in een Array te zetten en later op te roepen
 
Is je ego soms gekrenkt of post je altijd zo'n onzinnige reacties? De implementatie van de game-server hoort op beide servers (dus lokaal of extern gehost) gewoon hetzelfde te werken. Dus het enige verschil met het huren van een server is dat deze een hogere snelheid biedt. (indien dat niet het geval is kun je de server net zo goed thuis hosten, mits je geen problemen hebt met een extra pc die 24/7 aan staat)
 
Is je ego soms gekrenkt of post je altijd zo'n onzinnige reacties? De implementatie van de game-server hoort op beide servers (dus lokaal of extern gehost) gewoon hetzelfde te werken. Dus het enige verschil met het huren van een server is dat deze een hogere snelheid biedt. (indien dat niet het geval is kun je de server net zo goed thuis hosten, mits je geen problemen hebt met een extra pc die 24/7 aan staat)

Ah, Maar is het een spel voor LAN gebruik of Wereldwijd,... :eek:
 
Ah, Maar is het een spel voor LAN gebruik of Wereldwijd,... :eek:

Als het onder LAN ook niet goed werkt dan is de code gewoon slecht, want dan zal een gehoste game-server niet veel voordeel bieden :p

(is vrij makkelijk te testen voor de TS)
 
Als het onder LAN ook niet goed werkt dan is de code gewoon slecht, want dan zal een gehoste game-server niet veel voordeel bieden :p

(is vrij makkelijk te testen voor de TS)

Ik denk dat het daar fout gelopen is met je conclusie op mijn antwoord:
Als het LAN is kan je gewn rechtstreeks verstuuren en voor wereldwijd heb je Server nodig
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan