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

11

25.06.2007, 15:36

Hallo!
Danke für alles!
ICh probiere das jetzt mit fd_set zu machen.
Doch bei dem Select befehl gibt er immer ein error aus!
(Fehlercode: 10038)
Hier mal der codeausschnitt:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
bool CServer::run()
{

    //..........Socketbuffer füllen.........................


    FD_ZERO(&Server.Socketbuffer);  //Inhalt zunächst leeren


    for (int i=0; i<Server.maxClients; i++)
        if (!Server.Clients[i].free)
            FD_SET(Server.Clients[i].Clientsocket,&Server.Socketbuffer);        //Alle Alten clienten wieder hinzufügen


    FD_SET(Server.Serversocket,&Server.Socketbuffer);   //Neuen Clienten auch hinzufügen!


    //..........Socketbuffer füllen.........................


    

    //....................Events Abfragen..................

    if (select( 0,&Server.Socketbuffer,NULL,NULL,NULL)==SOCKET_ERROR )
        return false;
    //....................Events Abfragen..................


...

Faule Socke

Community-Fossil

Beiträge: 1 915

Wohnort: Schreibtischstuhl

  • Private Nachricht senden

12

25.06.2007, 16:01

Wo ist Server denn deklariert?

Socke

EDIT
Du kannst ja auch einfach eine beschreibung des fehlers ausgeben:
schau dir mal die FUnktion FormatMessage an.


Socke

13

25.06.2007, 16:44

Zitat

Du kannst ja auch einfach eine beschreibung des fehlers ausgeben:
schau dir mal die FUnktion FormatMessage an.


Ok das habe ich gemacht.
Er sagt, dass sich der Vorgang auf ein socket bezieht, das kein socket ist!

aber select ist doch so aufgebaut:

C-/C++-Quelltext

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


Da ist doch garkein socket oder?
(bzw. nur fd_set ist ja ein socket arry)
was stimmt denn da nicht?

Gruß Flo

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

14

25.06.2007, 18:10

ein Bleistift, wie es bei mir geht. schau mal auch ob die Socket, die du einfügst auch korrekt sind.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
DWORD BasicServer::empfangenClients(LPVOID p)
{ 
    BasicServer* server = static_cast<BasicServer*>(p);
    server->status = READY;
    
    TIMEVAL time = { 3, 0 };

    fd_set readset;
    while(server->status = READY)
    {

        FD_ZERO(&readset);
        FD_SET(server->Socket, &readset);

        for(std::list<BasicServerClient*>::iterator temp = server->ClientList.begin(); temp != server->ClientList.end(); temp++)
        {
            if((*temp)->status == READY)
                FD_SET((*temp)->Socket, &readset);
        }
        server->ClientList.unlock();

        if(SOCKET_ERROR == select(NULL, &readset, NULL, NULL, &time))
            server->geterror();

        for(std::list<BasicServerClient*>::iterator temp = server->ClientList.begin(); temp != server->ClientList.end(); temp++)
        {
            if(((*temp)->status == READY) && FD_ISSET((*temp)->Socket, &readset))
                (*temp)->ClientCallback();
        }
        server->ClientList.unlock();
    }
}
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.

15

25.06.2007, 20:14

Zitat

schau mal auch ob die Socket, die du einfügst auch korrekt sind.

Du hast recht!
Wenn ich das einfügen rausnehme klappt alles (ohne Fehlermeldung)
Irgendwas mache ich da falsch!

Danke für alles!
PS:

C-/C++-Quelltext

1
select(NULL, &readset, NULL, NULL, &time);

muss doch eigentlich

C-/C++-Quelltext

1
select(0, &readset, NULL, NULL, &time); 

heißen oder?

Viktor

Alter Hase

Beiträge: 533

Wohnort: Ludwigshafen

Beruf: Student

  • Private Nachricht senden

16

25.06.2007, 20:32

Ich dachte das waere nur eine Stielfrage, ob man NULL oder 0 schreibt. Muesste doch im Prinzip das gleiche sein...

David_pb

Community-Fossil

Beiträge: 3 886

Beruf: 3D Graphics Programmer

  • Private Nachricht senden

17

25.06.2007, 20:37

Zitat von »"Stier X"«

Ich dachte das waere nur eine Stielfrage, ob man NULL oder 0 schreibt. Muesste doch im Prinzip das gleiche sein...


Genau, bei C++ ist es haargenau das Selbe! ;-)
@D13_Dreinig

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

18

25.06.2007, 21:02

Dann zeig doch mal, wie du deine Clients empfängst und in dein Array packst.
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.

19

26.06.2007, 10:41

Ok.
Also ersteinmal die Server und Client structur:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
//------------------------Clientstructur--------------------------------

struct SClient
{
    int id;                         //Die zugeteilte ID

    char Name[20];                  //Der Name des Clienten (wird beim login gleich empfangen)

    SOCKET Clientsocket;            //Der Socket des Clienten

    bool free;                      //Ob der Client schon benutzt ist oder frei ist


    SClient(){
    free=true;
    Clientsocket=INVALID_SOCKET;
    }
};
//------------------------Clientstructur--------------------------------







//------------------------Serverstructur--------------------------------

struct SServer
{
    char Servername[20];        //Der Servername

    int Port;                   //Der Serverport

    int numClients;             //Anzahl der Clienten, die online sind

    int maxClients;             //Anzahl der maximalen Clienten


    SClient* Clients;           //dynamischer Speicher für die Clienten!


    SOCKET Serversocket;        //Der Serversocket

    SOCKADDR_IN Serveradresse;  //Die Serveradresse

    FD_SET Socketbuffer;        //Der Socketbuffer (wird jedes mal neu gefüllt)

};
//------------------------Serverstructur--------------------------------


Dann hier mal die run() funktion des Servers:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
//-----------------------Client einloggen-------------------------------------------

bool CServer::Login(int id)
{
     //....Structur füllen....

        Server.Clients[id].free=false;
        Server.Clients[id].id=id;
        Server.Clients[id].Clientsocket=accept(Server.Serversocket,NULL,NULL);      
        recv(Server.Clients[id].Clientsocket,Server.Clients[id].Name,21,0);

        cout << "Neuer Client: " << Server.Clients[id].Name << endl;
      //....Structur füllen....

    return true;     
}
//-----------------------Client einloggen-------------------------------------------




//-----------------------Server laufen lassen---------------------------------------

bool CServer::run()
{

    //..........Socketbuffer füllen.........................


    FD_ZERO(&Server.Socketbuffer);  //Inhalt zunächst leeren

    
    FD_SET(Server.Serversocket,&Server.Socketbuffer);   //Neuen Clienten auch hinzufügen!

    
    for (int i=0; i<Server.maxClients; i++)
        if (!Server.Clients[i].free && Server.Clients[i].Clientsocket!=INVALID_SOCKET)
        {
            FD_SET(Server.Clients[i].Clientsocket, &Server.Socketbuffer);       //Alle Alten clienten wieder hinzufügen

        }


    //..........Socketbuffer füllen.........................


    

    //....................Events Abfragen..................

    if (select( 0,&Server.Socketbuffer,NULL,NULL,NULL)==SOCKET_ERROR)
       return false;
    //....................Events Abfragen..................



    //............Prüfen ob ein Neuer Client da ist........

    if(FD_ISSET( Server.Serversocket, &Server.Socketbuffer )) {
        
        //neuer Client

            
        Login(getfreeID()); //neue id suchen und einloggen

        
    }
    //............Prüfen ob ein Neuer Client da ist........




    //............Messages weiterleiten an eine id.........

    for (int i=0; i<Server.maxClients; i++)
    {
        if (Server.Clients[i].free)
            continue;

        if (FD_ISSET(Server.Clients[i].Clientsocket,&Server.Socketbuffer))
        {
        SHeader Header;

        if (recv(Server.Clients[i].Clientsocket,(char*) &Header,sizeof(SHeader),0)==SOCKET_ERROR)
        {
            //Client ist nich mehr da!

            Server.Clients[i].free=true;
            closesocket(Server.Clients[i].Clientsocket);
            Server.Clients[i].id=50;
            cout << Server.Clients[i].Name << " hat sich abgemeldet!" << endl;
        }else{
            //Client hat etwas geschickt!

            void* packet;

            recv(Server.Clients[i].Clientsocket,(char*) &packet,Header.size,0);
            cout << (char*) packet << endl;
            
            if (Header.empfaenger==ALL)
            {
              for (int x=0; x<Server.maxClients; x++)
              {
              send(Server.Clients[x].Clientsocket,(char*) &Header, sizeof(SHeader),0); //Header schicken

              send(Server.Clients[x].Clientsocket,(char*) &packet, Header.size,0);  //Paket schicken    

              }
                                       
            }else{
            send(Server.Clients[Header.empfaenger].Clientsocket,(char*) &Header, sizeof(SHeader),0); //Header schicken

            send(Server.Clients[Header.empfaenger].Clientsocket,(char*) &packet, Header.size,0);    //Paket schicken

            }
        }

        }

    }
    //............Messages weiterleiten an eine id......... 

    
    
    return true;
}
//-----------------------Server laufen lassen---------------------------------------


Bei mir leitet der Server die Nachrichten nur an einen clienten weiter.
Aber das ist zunächst unwichtig.
Nur der Anfang der run funktion zählt ;)

Dann nocheinmal die funktion, wo die anzahl der maximalen clienten eingestellt wird:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//------------------------Setzt die Maximale Anzahl von Clients---------------------

bool CServer::setMaxClients(int num)
{

    Server.maxClients=num;  

    Server.Clients = new SClient[Server.maxClients+1];
    
    for(int i=0;i<Server.maxClients;i++) 
    {
    Server.Clients[i].Clientsocket=INVALID_SOCKET;
    Server.Clients[i].free=true;
    }



    return true;
}
//------------------------Setzt die Maximale Anzahl von Clients---------------------


Wo ist der Fehler?

Guß Flo

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

20

26.06.2007, 12:48

Nebenbei:

C-/C++-Quelltext

1
2
3
4
            //Client hat etwas geschickt! 

            void* packet; 

            recv(Server.Clients[i].Clientsocket,(char*) &packet,Header.size,0); 


Wenn das nicht crashed bin ich erstaunt. Außerdem habe ich die Erfahrung gemacht, dass accept scheitert, wenn es nicht in einem eigenen Thread ist, also direkt aufgerufen wird.

C-/C++-Quelltext

1
2
     Server.Clients[id].Clientsocket=accept(Server.Serversocket,NULL,NULL);        
        recv(Server.Clients[id].Clientsocket,Server.Clients[id].Name,21,0); 


Nach dem accept solltest du auf INVALID_SOCKET prüfen.
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.

Werbeanzeige