Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

$nooc

Alter Hase

  • »$nooc« ist der Autor dieses Themas

Beiträge: 873

Wohnort: Österreich / Kärnten

Beruf: Schüler

  • Private Nachricht senden

11

22.12.2007, 12:35

so.. ich hab jetzt den fehler etwas eingrenzen können..

der server blockiert, weil mein m_acceptSocket im fdSetRead NACH select() noch immer enthalten ist..

d.h. bei

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
        if(FD_ISSET(m_acceptSocket, &fdSetRead))
        {
            newConnection.socket    = accept(m_acceptSocket, (SOCKADDR*)&newConnection.addr, &addrsize);
            freeClientSlot          = getFreeClientSlot();

            if(freeClientSlot == -1)
                continue;

            m_Client[freeClientSlot]        = newConnection;
            m_Client[freeClientSlot].used   = true;

                return 1;*/
        }


wird accept() aufgerufen..

WIESO ist m_acceptSocket noch im fdSetRead enthalten? sollte doch von select() rausgenommen worden sein oder? O_o
Am Anfang der Weisheit steht die eigene Erkenntnis, dass man selbst nichts weiß! - Sokrates

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

12

22.12.2007, 14:30

Wo rufst du denn listen() auf? Weil normal sollte der Socket von deinem Server nur drinne sein, wenn wirklich eine Verbindung reingekommen ist (soweit ich weiß). Könntest du vielleicht mal den gesamten Code aus der CPP bei http://nopaste.info/ o.ä. posten?
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

$nooc

Alter Hase

  • »$nooc« ist der Autor dieses Themas

Beiträge: 873

Wohnort: Österreich / Kärnten

Beruf: Schüler

  • Private Nachricht senden

13

22.12.2007, 14:36

ok.. also hier ist der code:

http://rafb.net/p/kokOzp17.html

*edit:
also listen() wird aufgerufen, bevor die hauptschleife beginnt.. m_acceptSocket wird auf listening gesetzt, und dann wird nur noch process() in einer endlosschleife aufgerufen (siehe code)

ich muss listen() doch nur 1mal aufrufen oder? oder muss m_acceptSocket() nach annehmen einer verbindung wieder auf listening gesetzt werden?

*edit2:

Zitat von »"MSDN"«


C-/C++-Quelltext

1
2
3
4
5
6
7
int select(
  __in     int nfds,
  __inout  fd_set* readfds,
  __inout  fd_set* writefds,
  __inout  fd_set* exceptfds,
  __in     const struct timeval* timeout
);


The parameter readfds identifies the sockets that are to be checked for readability. If the socket is currently in the listen state, it will be marked as readable if an incoming connection request has been received such that an acceptis guaranteed to complete without blocking. For other sockets, readability means that queued data is available for reading such that a call to recv, WSARecv, WSARecvFrom, or recvfrom is guaranteed not to block.


demnach wird mein m_acceptSocket im fdSetRead gelassen, sobald eine verbindung aufgebaut werden soll..

aber danach bleibt es aus irgendeinem grund drinnen, obwohl sich nur 1 client verbunden hat, und kein weiterer sich verbinden will
Am Anfang der Weisheit steht die eigene Erkenntnis, dass man selbst nichts weiß! - Sokrates

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

14

22.12.2007, 15:24

listen muss nur einmal gestartet werden, aber du rufst in dem Code nie startWinsocket auf.

Auch kannst du das vereinfachen:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Client newConnection;
int addrsize = sizeof(SOCKADDR_IN);
int freeClientSlot;
 
if(FD_ISSET(m_acceptSocket, &fdSetRead))
{
    newConnection.socket    = accept(m_acceptSocket, (SOCKADDR*)&newConnection.addr, &addrsize);
    freeClientSlot      = getFreeClientSlot();
 
    if(freeClientSlot != -1)
    {
 
            m_Client[freeClientSlot]         = newConnection;
            m_Client[freeClientSlot].used   = true;
    }
}


Außerdem würde ich nur auf die Fehlercodes prüfen und solche Sachen wie if(ret < 0) eher verzichten, aber das ist nur eine persönliche Meinung
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

$nooc

Alter Hase

  • »$nooc« ist der Autor dieses Themas

Beiträge: 873

Wohnort: Österreich / Kärnten

Beruf: Schüler

  • Private Nachricht senden

15

22.12.2007, 15:39

Zitat von »"Nox"«

listen muss nur einmal gestartet werden, aber du rufst in dem Code nie startWinsocket auf.


der constructor der klasse sieht so aus:

C-/C++-Quelltext

1
Server  () { startWinsocket(); }



Zitat von »"Nox"«


Auch kannst du das vereinfachen:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Client newConnection;
int addrsize = sizeof(SOCKADDR_IN);
int freeClientSlot;
 
if(FD_ISSET(m_acceptSocket, &fdSetRead))
{
    newConnection.socket    = accept(m_acceptSocket, (SOCKADDR*)&newConnection.addr, &addrsize);
    freeClientSlot      = getFreeClientSlot();
 
    if(freeClientSlot != -1)
    {
 
            m_Client[freeClientSlot]         = newConnection;
            m_Client[freeClientSlot].used   = true;
    }
}



nicht nur vereinfachen, sondern auch logischer abändern.. normal müsste ich ja zuerst überprüfen ob überhaupt ein freier slot zur verfügung steht, und erst danach die verbindung annehmen.. aber der code stammt aus einem tutorial, und hab da noch keine verbesserungen vorgenommen..


Zitat von »"Nox"«


Außerdem würde ich nur auf die Fehlercodes prüfen und solche Sachen wie if(ret < 0) eher verzichten, aber das ist nur eine persönliche Meinung


auf die fehlerbehandlung bin ich noch nicht so genau eingegangen, das hab ich verschoben auf den zeitpunkt, sobald mein server die erste nachricht empfangen kann, und auf den client zurück schicken kann..
also fehlerabfragen usw. kommen noch..

....................

zu meinem problem, wieso m_acceptSocket noch im fdSetRead ist, hast du nichts gefunden?

....................
Am Anfang der Weisheit steht die eigene Erkenntnis, dass man selbst nichts weiß! - Sokrates

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

16

22.12.2007, 15:55

achso, das Problem tritt also erst auf nachdem du ein connect durchgeführt hast. Dann ist es klar, weil die Schleife wird ja nicht nur einmal ausgeführt und beim 2. Durchlauf ist der Socket natürlich immernoch gesetzt.

for(x = 0; x < fdSetRead.fd_count; x++)

muss raus. Geht es dann?
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

$nooc

Alter Hase

  • »$nooc« ist der Autor dieses Themas

Beiträge: 873

Wohnort: Österreich / Kärnten

Beruf: Schüler

  • Private Nachricht senden

17

22.12.2007, 16:15

nein nein.. es läuf t so ab:

process() wird permanent aufgerufen..

--> client connected..

process() wird ausgeführt..
--> nimmt verbindung an..
process() fertig..

process() wird erneut aufgerufen:

whie(1)
{
server.process();
}

und erst genau da geht der in die accept funktion rein und bleibt da..
Am Anfang der Weisheit steht die eigene Erkenntnis, dass man selbst nichts weiß! - Sokrates

rklaffehn

Treue Seele

Beiträge: 267

Wohnort: Braunschweig

  • Private Nachricht senden

18

22.12.2007, 16:46

Das klingt mir nun wirklich so, als würde eine lokale Variable für fd_set die Lösung sein...

Dann kann dir eine alte Meldung nicht einfach so zwischen verschiedenen Aufrufen erhalten bleiben.
God is real... unless declared integer.
http://www.boincstats.com/signature/user_967277_banner.gif

$nooc

Alter Hase

  • »$nooc« ist der Autor dieses Themas

Beiträge: 873

Wohnort: Österreich / Kärnten

Beruf: Schüler

  • Private Nachricht senden

19

22.12.2007, 16:53

das hab ich bereits geändert... und das problem ist das gleiche

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
int Server::process ()
{
    unsigned int x, ret;

    fd_set fdSetRead;

    FD_ZERO(&fdSetRead);

    FD_SET(m_acceptSocket, &fdSetRead);

    // ...
Am Anfang der Weisheit steht die eigene Erkenntnis, dass man selbst nichts weiß! - Sokrates

$nooc

Alter Hase

  • »$nooc« ist der Autor dieses Themas

Beiträge: 873

Wohnort: Österreich / Kärnten

Beruf: Schüler

  • Private Nachricht senden

20

22.12.2007, 18:02

HIER kann man sich wer will die paar zeilen runterladen und sie compilieren. vllt. findet jemand beim debuggen einen fehler..

--> Visual Studio 2005
Am Anfang der Weisheit steht die eigene Erkenntnis, dass man selbst nichts weiß! - Sokrates

Werbeanzeige