Windows Socket - Meerder clienten vanaf zelfde pc doen clients flippen...

Status
Niet open voor verdere reacties.

Xabre

Gebruiker
Lid geworden
22 sep 2007
Berichten
55
Hoi,


Ik heb een blocking server gemaakt met standaard socket API, blocking omdat ik mij niet kan herinneren dak ik dit heb ingesteld, + de client wacht op de server ipv wachten op een event.

Nu heb ik het volgende probleem :
Als ik meerdere client-sockets open, krijgt enkel de laatst geopende de gegevens binnen! Wanneer ik via de overige clienten iets wil versturen/ontvangen loop deze allemaal vast. Ik denk dat het iets te maken heeft met de server die al de gegevens (opgevraagd door één client op dezelfde poor) naar alle clienten ,die (op die poort ) aan het meeluisteren zijn, wil zenden.

Ook wil ik erbij vermelden dat ik ,nadat de client heeft ingelogd, de socket niet meer sluit. Het gemiddelde aan gebruikers die ter gelijkertijd online zouden zijn verwacht ik 10 tot max 20.

Kan iemand mij helpen aub!
Thx
 
Gebeurt dit echt alleen als er meerdere cliënten op een pc zitten, of ook als ze op verschillende pc's zitten. De titel van het onderwerp suggereert van wel. Uit de tekst is dit voor mij niet helemaal duidelijk.
(Is dit trouwens het programma met die SCLIENT-klasse waar je al eerder over had gepost i.v.m. een Mutex?)
 
hoi,

het gebeurt ook als er clients vanop verschillende pc's inloggen, had dit nog niet getest maar het gebeurt toch:s ja het is inderdaad ivm de SCLIENT klasse. Sorry voor de onduidelijkheid:o

Ik denk dat ik zojuist mijn fout heb gevonden!?:s In mijn code staat er
accept( SSocket, NULL, NULL );
waar de 2de parameter het adres is waarnaar deze moet zenden en al...

Code:
SOCKET accept(
  __in     SOCKET s,
  __out    struct sockaddr* addr,
  __inout  int* addrlen
);

Ik heb ondertussen de code aangepast
Code:
if( listen( SSocket,63000 ) == 0 )
                          {
                              IWantMore = true;
                             // ioctlsocket(SSocket,FIONBIO,(u_long *)1);
                          }
                        
                          memset(&echoClientAddr,0,sizeof(echoClientAddr));
                          clientDSlength = sizeof(echoClientAddr);
                        
                          ClientSocket = accept( SSocket, (struct sockaddr*) &echoClientAddr, (int *)&clientDSlength );
                          
                          if (ClientSocket == INVALID_SOCKET) {	        	
	                 	       Disconnect();
	                 	       DeadlyIdleClient = true;
	           	               return WSAGetLastError();
                          }
                          
                          Error( inet_ntoa( echoClientAddr.sin_addr) );   
                          
                          int Data_Of_Thread_3 = 3;
                          ClientHandle = CreateThread( NULL, 0,ClientThread, (void *)this, 0, NULL);
                          DeadlyIdleClient = false;
                          
                          Mutex = CreateMutex( 
                          NULL,              // default security attributes
                          FALSE,             // initially not owned
                          "SCLIENT");

Nu heb ik het volgende probleem gekregen : Er is maar 1 client die nog kan connecten:s
ik moet de server herstarten om een andere toe te laten, als die eerste client afsluit en dan opnieuw wil inloggen doet ie het niet meer! (totdat ik de server reset:s)

Maar hiervoor heb ik ook al een oplossing gevonden! Nu moet ik enkel nog testen vanaf verschillende pc's want vanaf dezelfste pc loopt het nog altijd fout!
 
Laatst bewerkt:
Hmm, je geeft aan dat je een oplossing hebt gevonden, maar je geeft ook aan dat het nog fout gaat als er meerdere clienten op 1 pc zitten.

Ik denk dat je met maar 1 SOCKET werkt en de waarde iedere keer overschrijft als accept() is uitgevoerd.

accept kan je gewoon zo: accept( SSocket, NULL, NULL ); aanroepen tenzij je het adres van de client echt wil hebben. Voor het gebruik van send en recv is het niet nodig.
Listen hoef je slechts 1 keer succesvol aan te roepen. Daarna alleen accept in een lus.
In de code die je in een andere thread had gepost zaten zowel accept als listen in de functie SCLIENT::Init. Ik zou beide buiten de klasse houden.

Als je er niet uitkomt post dan indien mogelijk de code van de definitie van de SCLIENT-klasse en de lus die je gebruikt waarin accept telkens wordt aangeroepen en er nieuwe SOCKETS bijkomen.
 
Laatst bewerkt:
Hoe bedoel je? Dat ik slechts eenmaal listen moet uitvoeren?

Code:
listen();
while( true )
{
    accept();
}

En iedere client die wil connecten zal dan ge-connect worden?

Sorry van het warige bovengedeelte, had niet veel tijd om te debuggen:s
 
Ja zoiets bedoel ik listen slechts 1 keer aanroepen. Dat doe je als het goed is ook met bind().
 
Code:
#ifndef     __DBserver__
#define     __DBserver__ 0

#include    <winsock2.h>
#include    <vector.h>
#include    "Explode.h"

#include    "PDataBase.h"

DATABASE    *DB;

using       namespace std;

class       SCLIENT
{
            SOCKET   ClientSocket;                   
            
            friend DWORD WINAPI ClientThread( void * pParam )
            {                       
                  SCLIENT *temp = (SCLIENT *)pParam;
                  temp->Buffer = "";
                  
                  while ( !temp->DeadlyIdleClient )
                  {
                        Sleep( temp->WaitTime );
                        
                        if( temp->Buffer == "" )
                        {   
                            temp->ReceiveData();
                            
                            if( temp->WaitTime < 500 )
                                   temp->WaitTime ++;
                        }
                        else
                        {                                   
                               temp->DoAsk("");
                               temp->Buffer = "";
                               temp->WaitTime = 1;                                                                       
                        }
                  }
                   
                  return 0;
            }
                        
            public:
                   bool Init(SOCKET   SSocket,HWND &LogScr_ )
                   {
                          LogScreen = LogScr_;
                   
                          SendMessageToHost("[LOG] Connected!\n");             
                        
                          ClientSocket = SSocket;
                          
                          if (ClientSocket == INVALID_SOCKET) {	        	
	                 	       Disconnect();
	                 	       DeadlyIdleClient = true;
	                 	       Error( "Error Connecting client..." );  
	           	               return WSAGetLastError();
                          }
                          
                          int Data_Of_Thread_3 = 3;
                          ClientHandle = CreateThread( NULL, 0,ClientThread, (void *)this, 0, NULL);
                          DeadlyIdleClient = false;
                          
                          Mutex = CreateMutex( 
                          NULL,              // default security attributes
                          FALSE,             // initially not owned
                          "SCLIENT");
                          
                          WaitTime = 1;
                          
                          return true;
                   }
                   
                   HWND     LogScreen;
                   HANDLE   ClientHandle;
                   HANDLE   Mutex;
                   
                   bool     DeadlyIdleClient;
                   bool     IWantMore;
                   
                   string   Buffer;
                   char     *Text;
                   
                   string   DoAsk(string command);
                   
                   bool     SaveToErrorlog(char *str);
                   bool     SaveToServerlog(char *str);
                   
                   bool     Disconnect();
            
                   bool     SendData();
                   bool     ReceiveData();
                   
                   int      WaitTime;
};

bool        SCLIENT :: SaveToErrorlog(char *str)
{
            FILE *LogFile;
            LogFile = fopen("LOGS/errors.log","a+");
            
            fputs( str,LogFile );
                        
            fclose(LogFile);
            delete LogFile;
}

bool        SCLIENT :: SaveToServerlog(char *str)
{
            FILE *LogFile;
            LogFile = fopen("LOGS/server.log","a+");
            
            fputs( str,LogFile );
            
            fclose(LogFile);
            
            delete LogFile;
}

bool        SCLIENT :: SendData( )
{
            int iResult = send(ClientSocket,(char *)Buffer.c_str(),Buffer.size(),0);
            
            if( WSAGetLastError() != 0 )
            {
                Disconnect(); 
            }
            else if( iResult == 0 )
            {
                return false;
            }
            else
                return iResult;
}

bool        SCLIENT :: ReceiveData()
{
            char buf[65000] = "";
            int iResult = recv(ClientSocket, buf, 65000, 0);
                           
            if( iResult == 0 || WSAGetLastError() != 0 )
            {
                Disconnect(); 
            }
            else
            {
                Buffer = buf;                  
                return 0;
            }
}

string      SCLIENT :: DoAsk(string command = "")
{            
            vector <string> cmd;
            cmd = Explode(command == "" ? Buffer : command," ");
            
            if( cmd.size() == 0 )
                return "";
            
            if( cmd.at(0) == "CLOSECON" )
            {                
                Disconnect();
                cmd.clear();
                return "[LOG] Disconnected!\n";
            }
            else if( cmd.at(0) == "ERROR" )
            {                 
                 MessageBox(NULL, cmd.at(1).c_str() , "CLIENT ERROR" , MB_ICONERROR | MB_OK );
            }
            else if( cmd.at(0) == "DB_REQUEST" )
            {    
                 DWORD dwWaitResult = WaitForSingleObject( 
                            Mutex,    // handle to mutex
                            INFINITE);
                 
                 if( dwWaitResult == WAIT_OBJECT_0 )
                 {         
                      string ID = DB->Connect( cmd.at(1),cmd.at(2) );
             
                      if( ID == "ILLIGAL_ATTEMPT" )
                      {  
                         string RetValue = "\n[ERROR] ILLIGAL ATTEMPT TO ACCES DB-SERVER : " + cmd.at(1) + "@" + cmd.at(2);
                     
                         SendMessageToHost( (char *)RetValue.c_str() );
                         cmd.clear();
                    
                         return "HALT";
                      }

                      vector <string> Requests = Explode(command == "" ? Buffer : command,"<=>");
                 
                      if( Requests.size() > 1 )
                      {                 
                          vector <string> Query = DB->Command(ID, Requests.at(1) );
                 
                          Buffer = "OK";
                 
                          for(int i = 0;i < Query.size();)
                          {
                              //Error((char *)Buffer.c_str());
                              if( Buffer == "OK" )
                              {
                                  Buffer = Query.at(i) == "" ? "NULL" : Query.at(i);                                  
                                  SendData();
                                  Buffer = "";
                                  ReceiveData();
                                  i++;
                              }                   
                          }                 
                          
                          Buffer = "EODBI";
                          SendData();
                      }
                      else
                      {
                          Buffer = "NO_CORRECT_REQUEST : Please ask your software distributor for solutions";
                          SendData();
                          
                          ReceiveData();
                          if( Buffer == "OK" )
                          {
                              Buffer = "EODBI";
                              SendData();
                              }
                      }
                 
                      Requests.clear();
                      
                      ReleaseMutex(Mutex);
                 }
            }
            
            cmd.clear();
            
            return "";
}

bool        SCLIENT :: Disconnect()
{
            closesocket(ClientSocket);
            DeadlyIdleClient = true;
            
            return 0;
}

class       SSERVER
{         
       private:               
            WSADATA  wsaData;

            SOCKADDR_IN SocketAddres;
            SOCKET   Socket;
            SOCKET   ClientSocket;
            
            char     *Address;
            int      Port;
            
            int      MaximumConnections;            
            bool     Server;
            
            SCLIENT  Temp;
            vector<SCLIENT> ClientsVector;
            
       public:           
            SSERVER(char b0,char b1,char b2,char b3,unsigned int port,int maxCons = 1,bool server = true)
            {                         
                  MaximumConnections = maxCons;
                  _lastErrorCode = -1;
                         
                  if( WSAStartup(MAKEWORD(2,2),&wsaData) != 0 )
                  {
                      _lastErrorCode = WSAGetLastError();
                  }   
                  
                  Socket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
                  
                  if( Socket == INVALID_SOCKET )
                  {
                      _lastErrorCode = WSAGetLastError();
                  }
                  
                  SocketAddres.sin_port = htons(port);
                  SocketAddres.sin_family = AF_INET;

	              
                  if( b0 == 127 && b1 == 0 && b2 == 0 && b3 == 1 )
                  {
                       SocketAddres.sin_addr.S_un.S_un_b.s_b1 = 0;
	                   SocketAddres.sin_addr.S_un.S_un_b.s_b2 = 0;
	                   SocketAddres.sin_addr.S_un.S_un_b.s_b3 = 0;
	                   SocketAddres.sin_addr.S_un.S_un_b.s_b4 = 0;
                  }
                  else
                  {
                       SocketAddres.sin_addr.S_un.S_un_b.s_b1 = b0;
	                   SocketAddres.sin_addr.S_un.S_un_b.s_b2 = b1;
	                   SocketAddres.sin_addr.S_un.S_un_b.s_b3 = b2;
	                   SocketAddres.sin_addr.S_un.S_un_b.s_b4 = b3;
                  }
                  
                  Server = server;                           
            }
            ~SSERVER()
            {
            }                                    
            int      _lastErrorCode;
            char     *ExplainError( int code );
            
            bool     Connect();            
            bool     Listen(HWND &hwnd);
            
            vector<char *> CommandList;
};

bool        SSERVER :: Connect()
{
            
            if( !Server )
            {
                        ClientSocket = socket(AF_INET,SOCK_STREAM,0);
                
                        if( ClientSocket == INVALID_SOCKET || 
                            connect(ClientSocket,(SOCKADDR*)(&SocketAddres),sizeof(SocketAddres) ) == SOCKET_ERROR )
                        {
                            _lastErrorCode = WSAGetLastError();                
                            return WSAGetLastError();
                        }
            }
            else
            {
                        if( bind(Socket,(SOCKADDR*)(&SocketAddres),sizeof(SocketAddres) ) == SOCKET_ERROR )
                        {
                            _lastErrorCode = WSAGetLastError();                
                            return WSAGetLastError();
                        }
                        
                        bool bOptVal = true;
                        int bOptLen = sizeof(BOOL);
                        setsockopt(Socket, SOL_SOCKET, SO_BROADCAST, (char*)&bOptVal, bOptLen);
            }            
            
            return 0;
}

bool        SSERVER :: Listen(HWND &hwnd)
{            
                if( Server )
                {                                                   
                        listen(Socket,255);
                        while( true )
                        {                          
                          SOCKET ForClient = accept( Socket,NULL,NULL);
                        
                            if( ForClient != INVALID_SOCKET )
                            {
                                   Temp.Init(ForClient,hwnd );
                                   ClientsVector.push_back( Temp );
                            }
                        }                       
                }
}

char        *SSERVER :: ExplainError( int code )
{
            switch( code )
            {
                    default : return "No error code like that in our register!\n";
            }
}
#endif
 
Laatst bewerkt:
Hoi,

Bovenstaande is de code die ik nu gebruik, bovenaan de client klasse
onderaan de server klasse...

Nu heb ik je raad opgevolgd...maar ik kan nog altijd geen meerdere clienten koppelen aan éénzelfde server!
 
Ik zal er eens naar kijken en er morgen (of eigenlijk later vandaag) iets over proberen te zeggen.
 
echt hartstikke bedankt dat je dit wilt doen! Ik kan U niet zeggen hoe dankbaar ik je ben! Maar ik ben heel dankbaar!
 
Ik heb een aantal punten opgegeven het belangrijkste is 1) en ook 6) de rest zijn meer tips.

1) in SSERVER::Listen
Zoals ik al vermoedde: je overschrijft de waarde van de SOCKET.
Je gebruikt hier steeds variabele Temp voor nieuwe clienten. Als SCLIENT::Init aangeroepen wordt wordt the this pointer meegegeven aan een nieuwe thread deze pointer wijst nu altijd naar temp dus zal alleen de laatste client reactie krijgen, overigens wel van meerdere threads tegelijkertijd... Ik zie dat je een vector gebruikt om de temp in op te slaan. Ik ben zelf niet zo bekend met hoe een vector (en anderen dingen van stl) werkt je zou SCLIENT::Init miscchien aan kunnen roepen op het element van de vector. Anders zou je iets met dynamische allocatie en/of een gelinkte lijst moeten doen.
In ieder geval SCLIENT::Init op verschillende instanties van de SCLIENT klasse aanroepen.

2) in SCLIENT::receive
De waarde van WSAGetLastError() is niet altijd nul als er geen error is. Gebruik daarom liever een andere conditie om op fouten test zoals in SCLIENT::Receive.
dit:if( iResult == 0 || WSAGetLastError() != 0 )
wordt dan : if( iResult == 0 || iresult==SOCKET_ERROR )
De waarde van WSAGetLastError() gebruik je toch niet.

3) in ClientThread
Als recv blokkeert al er geen data is heeft temp->WaitTime ++ in de ClientThread() toch niet zoveel zin?

4) in SCLIENT::Init()
Als ClientSocket==INVALID_SOCKET waar is heeft het ook geen zin om Disconnect() aan te roepen. closesocket() doet dan niets met de socket.

5) in SCLIENT::Init()
maak de mutex voordat je een nieuwe thread maakt. Het kan ook met 1 handle. Misschien is de mutex niet eens nodig.

6) in SCLIENT::SaveToErrorlog() en SCLIENT::SaveToServerlog()
De FILE* die je van fopen moet enkel gesloten worden met fclose(). delete LogFile; moet dus weg.

7) in SCLIENT::SendData()
ook hier eerst testen of er wel een fout is door iresult==SOCKET_ERROR en dan evt. WSAGetLastError aanroepen.

8) in SCLIENT::SendData()
In SendData staat return iResult; en SendData() geeft eigenlijk een bool terug. Als Disconnect() aangeroepen wordt en er een error is wordt er helemaal niets geretourneerd.

9) Waarschijnlijk doe je het al in een ander deel van het programma, maar vergeet ook niet om de handles van de draad en mutex te sluiten met CloseHandle() als ze niet meer nodig zijn.
 
Ok, dus ik veronderstel dat het normaal is dat het systeem blokkeert als er meerdere clienten
vanaf dezelfde pc op de server zitten? Ik kan mij geen manier voorstellen die iedere socket verbinding uniek maakt. Alvast bedankt voor alles ik ben er mee bezig geweest, maar heb enkel nog maar kunnen testen van meerdere clienten vanaf zelfe host...deze liep momenteel vast...
 
OMG...
OMG...
OMG...
OMG...
OMG...
OMG...
OMG...


IK BEN U ZOVEEL VERSCHULDIGD! OMG het werkt! meerdere clienten per host!!

I could kiss you! (but I won't) Hieronder zal ik de code posten voor mensen die enigzins problemen zouden hebben!
Code:
#ifndef     __DBserver__
#define     __DBserver__ 0

#include    <winsock2.h>
#include    <vector.h>
#include    "Explode.h"

#include    "PDataBase.h"

DATABASE    *DB;

using       namespace std;

//          De aanroep van de struct SSERVER

class       SCLIENT
{           
            friend DWORD WINAPI ClientThread( void * pParam )
            {                       
                  SCLIENT *temp = (SCLIENT *)pParam;
                  temp->Buffer = "";
                  
                  while ( !temp->DeadlyIdleClient )
                  {
                        Sleep( temp->WaitTime );
                        
                        if( temp->Buffer == "" )
                        {   
                            temp->ReceiveData();
                            
                            if( temp->WaitTime < 500 )
                                   temp->WaitTime ++;
                        }
                        else
                        {                                   
                               temp->DoAsk("");
                               temp->Buffer = "";
                               temp->WaitTime = 1;                                                                       
                        }
                  }
                   
                  return 0;
            }
                        
            public:
                   bool Init(SOCKET   SSocket,HWND &LogScr_ )
                   {
                          LogScreen = LogScr_;
                   
                          SendMessageToHost("[LOG] Connected!\n");             
                        
                          ClientSocket = SSocket;
                          
                          if (ClientSocket == INVALID_SOCKET) {	        	
	                 	       Disconnect();
	                 	       DeadlyIdleClient = true;
	                 	       Error( "Error Connecting client..." );  
	           	               return WSAGetLastError();
                          }
                          
                          int Data_Of_Thread_3 = 3;
                          ClientHandle = CreateThread( NULL, 0,ClientThread, (void *)this, 0, NULL);
                          DeadlyIdleClient = false;
                          
                          Mutex = CreateMutex( 
                          NULL,              // default security attributes
                          FALSE,             // initially not owned
                          "SCLIENT");
                          
                          WaitTime = 1;
                          Connected = true;
                          
                          return true;
                   }
                   
                   HWND     LogScreen;
                   HANDLE   ClientHandle;
                   HANDLE   Mutex;
                   
                   SOCKET   ClientSocket;
                                      
                   bool     DeadlyIdleClient;
                   bool     IWantMore;
                   bool     Connected;
                   
                   string   Buffer;
                   char     *Text;
                   
                   string   DoAsk(string command);
                   
                   bool     SaveToErrorlog(char *str);
                   bool     SaveToServerlog(char *str);
                   
                   bool     Disconnect();
            
                   bool     SendData();
                   bool     ReceiveData();
                   
                   int      WaitTime;
};

bool        SCLIENT :: SaveToErrorlog(char *str)
{
            FILE *LogFile;
            LogFile = fopen("LOGS/errors.log","a+");
            
            fputs( str,LogFile );
                        
            fclose(LogFile);
}

bool        SCLIENT :: SaveToServerlog(char *str)
{
            FILE *LogFile;
            LogFile = fopen("LOGS/server.log","a+");
            
            fputs( str,LogFile );
            
            fclose(LogFile);
}

bool        SCLIENT :: SendData( )
{
            int iResult = send(ClientSocket,(char *)Buffer.c_str(),Buffer.size(),0);
            
            if( WSAGetLastError() != 0 )
            {
                Disconnect(); 
            }
            else if( iResult == 0 )
            {
                return false;
            }
            else
                return iResult;
}

bool        SCLIENT :: ReceiveData()
{
            char buf[65000] = "";
            int iResult = recv(ClientSocket, buf, 65000, 0);
                           
            if( iResult == 0 || WSAGetLastError() != 0 )
            {
                Disconnect(); 
            }
            else
            {
                Buffer = buf;                  
                return 0;
            }
}

string      SCLIENT :: DoAsk(string command = "")
{            
            vector <string> cmd;
            cmd = Explode(command == "" ? Buffer : command," ");
            
            if( cmd.size() == 0 )
                return "";
            
            if( cmd.at(0) == "CLOSECON" )
            {                
                Disconnect();
                cmd.clear();
                return "[LOG] Disconnected!\n";
            }
            else if( cmd.at(0) == "ERROR" )
            {                 
                 MessageBox(NULL, cmd.at(1).c_str() , "CLIENT ERROR" , MB_ICONERROR | MB_OK );
            }
            else if( cmd.at(0) == "DB_REQUEST" )
            {    
                 DWORD dwWaitResult = WaitForSingleObject( 
                            Mutex,    // handle to mutex
                            INFINITE);
                 
                 if( dwWaitResult == WAIT_OBJECT_0 )
                 {         
                      string ID = DB->Connect( cmd.at(1),cmd.at(2) );
             
                      if( ID == "ILLIGAL_ATTEMPT" )
                      {  
                         string RetValue = "\n[ERROR] ILLIGAL ATTEMPT TO ACCES DB-SERVER : " + cmd.at(1) + "@" + cmd.at(2);
                     
                         SendMessageToHost( (char *)RetValue.c_str() );
                         cmd.clear();
                    
                         return "HALT";
                      }

                      vector <string> Requests = Explode(command == "" ? Buffer : command,"<=>");
                 
                      if( Requests.size() > 1 )
                      {                 
                          vector <string> Query = DB->Command(ID, Requests.at(1) );
                 
                          Buffer = "OK";
                 
                          for(int i = 0;i < Query.size();)
                          {
                              //Error((char *)Buffer.c_str());
                              if( Buffer == "OK" )
                              {
                                  Buffer = Query.at(i) == "" ? "NULL" : Query.at(i);                                  
                                  SendData();
                                  Buffer = "";
                                  ReceiveData();
                                  i++;
                              }                   
                          }                 
                          
                          Buffer = "EODBI";
                          SendData();
                      }
                      else
                      {
                          Buffer = "NO_CORRECT_REQUEST : Please ask your software distributor for solutions";
                          SendData();
                          
                          ReceiveData();
                          if( Buffer == "OK" )
                          {
                              Buffer = "EODBI";
                              SendData();
                              }
                      }
                 
                      Requests.clear();
                      
                      ReleaseMutex(Mutex);
                 }
            }
            
            cmd.clear();
            
            return "";
}

bool        SCLIENT :: Disconnect()
{
            closesocket(ClientSocket);
            DeadlyIdleClient = true;
            Connected = false;
            
            return 0;
}

class       SSERVER
{         
       private:               
            WSADATA  wsaData;

            SOCKADDR_IN SocketAddres;
            SOCKET   Socket;
            SOCKET   ClientSocket;
            
            char     *Address;
            int      Port;
            
            int      MaximumConnections;            
            bool     Server;
            
            SCLIENT  Temp;
            vector<SCLIENT> ClientsVector;
            
       public:           
            SSERVER(char b0,char b1,char b2,char b3,unsigned int port,int maxCons = 1,bool server = true)
            {                         
                  MaximumConnections = maxCons;
                  _lastErrorCode = -1;
                         
                  if( WSAStartup(MAKEWORD(2,2),&wsaData) != 0 )
                  {
                      _lastErrorCode = WSAGetLastError();
                  }   
                  
                  Socket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
                  
                  if( Socket == INVALID_SOCKET )
                  {
                      _lastErrorCode = WSAGetLastError();
                  }
                  
                  SocketAddres.sin_port = htons(port);
                  SocketAddres.sin_family = AF_INET;

	              
                  if( b0 == 127 && b1 == 0 && b2 == 0 && b3 == 1 )
                  {
                       SocketAddres.sin_addr.S_un.S_un_b.s_b1 = 0;
	                   SocketAddres.sin_addr.S_un.S_un_b.s_b2 = 0;
	                   SocketAddres.sin_addr.S_un.S_un_b.s_b3 = 0;
	                   SocketAddres.sin_addr.S_un.S_un_b.s_b4 = 0;
                  }
                  else
                  {
                       SocketAddres.sin_addr.S_un.S_un_b.s_b1 = b0;
	                   SocketAddres.sin_addr.S_un.S_un_b.s_b2 = b1;
	                   SocketAddres.sin_addr.S_un.S_un_b.s_b3 = b2;
	                   SocketAddres.sin_addr.S_un.S_un_b.s_b4 = b3;
                  }
                  
                  Server = server;                           
            }
            ~SSERVER()
            {
            }                                    
            int      _lastErrorCode;
            char     *ExplainError( int code );
            
            bool     Connect();            
            bool     Listen(HWND &hwnd);
            
            vector<char *> CommandList;
};

bool        SSERVER :: Connect()
{
            
            if( !Server )
            {
                        ClientSocket = socket(AF_INET,SOCK_STREAM,0);
                
                        if( ClientSocket == INVALID_SOCKET || 
                            connect(ClientSocket,(SOCKADDR*)(&SocketAddres),sizeof(SocketAddres) ) == SOCKET_ERROR )
                        {
                            _lastErrorCode = WSAGetLastError();                
                            return WSAGetLastError();
                        }
            }
            else
            {
                        if( bind(Socket,(SOCKADDR*)(&SocketAddres),sizeof(SocketAddres) ) == SOCKET_ERROR )
                        {
                            _lastErrorCode = WSAGetLastError();                
                            return WSAGetLastError();
                        }
                        
                        bool bOptVal = true;
                        int bOptLen = sizeof(BOOL);
                        setsockopt(Socket, SOL_SOCKET, SO_BROADCAST, (char*)&bOptVal, bOptLen);
            }            
            
            return 0;
}

bool        SSERVER :: Listen(HWND &hwnd)
{            
                if( Server )
                {       
                        SOCKET ForClient;
                                                                    
                        listen(Socket,5);
                        ClientsVector.resize(50);
                        ClientsVector.push_back( Temp );                   

                        while( true )
                        {   
                            ForClient = accept( Socket,NULL,NULL);
                        
                            for(int i = 0;i < ClientsVector.size();i++ )
                            {
                                      if( ForClient != INVALID_SOCKET && ClientsVector.at( i ).Connected == false )
                                      {
                                              ClientsVector.back().Init(ForClient,hwnd );
                                              ClientsVector.push_back( Temp );
                                              break;                               
                                      }                            
                            }
                        }                       
                }
}

char        *SSERVER :: ExplainError( int code )
{
            switch( code )
            {
                    default : return "No error code like that in our register!\n";
            }
}
#endif
 
Laatst bewerkt:
het werkt! meerdere clienten per host!!
Dat is eigenlijk ook niet zo bijzonder, meerdere clienten per host.

Werkt het nou zonder die mutex ook, volgens mij heb je die nu niet meer nodig, omdat elke clientsocket nu 1 thread heeft.
 
Ja ik weet dat meerdere clients per host niet bijzonder is:p maar het is hem de truc om het te laten werken:p Over de fout met de overschreven socket was ik nooit over gevallen, het is pas als je het zegt, dat het "aja juist"-effect optreed:p

Dit is ook een project geweest waar ik veel heb bijgeleerd over winsockets iets waar ik 2 weken geleden niets of niet veel van wist. Aangezien dat het meeste hier nieuw was kon ik niet verwezenlijken wat in mijn hoofd zat. Maar dankzij U is dit wel gelukt.

Nogmaals bedankt,
Ik zal vanavond of morgen eens kijken wat het effect is zonder mutex maar ik vrees ervoor, aangezien er toch meerdere threads hetzelfde geheugengebied willen veranderen...
 
Laatst bewerkt:
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan