Daemon der auf Socket listent

GreenRover

Grünschnabel
Hallo, ich schreibe bisher nur PHP und will / muss mich nun mal mit einem C Programm befassen.

Kann mir jemand etwas auf ie Sprünge helfen?

Es soll ein Daemon werden, welcher auf einem Socket listent (Port).

Leider habe ich 0 Plan wie man da ran gehen muß, da solche Funktionen in PHP nicht giebt.

Falls mir diesen ersten Schrit jemand etwas erklären könnte mit code beispieln am besten währe ich sehr dankbar.

Den Rest sollte ich den so hin bekommen, da alle anderen Funktionen des geplanten Programms für mich nichts neues währen.

PS: Die bezeichnung der bibliotheken für fopen() fsocketopen() und string verarbeitung währen auch noch recht wichtig.
 
Hallo,

GreenRover hat gesagt.:
Es soll ein Daemon werden, welcher auf einem Socket listent (Port).
„listent“?

Leider habe ich 0 Plan wie man da ran gehen muß, da solche Funktionen in PHP nicht giebt.
Falsch.

PS: Die bezeichnung der bibliotheken für fopen() fsocketopen() und string verarbeitung währen auch noch recht wichtig.
fopen() ist Teil der Standardbibliothek (stdio.h). fsocketopen() ist mir in C nicht bekannt. Grundlegende Stringverarbeitung ist auch Teil der Standardbibliothek (string.h).

Wenn du Informationen zur Socketprogrammierung benötigst, dann mach dich am besten mal bewaffnet mit den Stichworten „Berkeley Sockets“ auf den Weg zu Google.

Grüße,
Matthias
 
DANKE ERSTMAL

Was hältst du von folgeden code:
Den ahbe ich im Internetgefunden und wollte Ihn als basis verwenden. Meinst der ist geeigent. PS besonders wichtig sind bei mir multi client support.

Das heist, würde das so auch unter linux laufen?!

Code:
/*************************************************************************** 
Name:             selectchatsrv.cpp 
Autor:            www.c-worker.ch 
Comments:      deutsch/english 

Beschreibung:      
Zeigt wie man blocking calls umgehen kann indem man select verwendet. 
Mit select() kann ein Server geschrieben werden   welcher mehrere Clients handelt, 
ohne mehrere Threads zu erzeugen. 
Beim diesem Demo handelt es sich um einen kleinen Chat-Server der auf Port 1234 
läuft. Der client dazu heisst selectchatclient.cpp 

Description: 
Show how to use select() to write a server which handles multiple clients in 
just one thread. It's a little chat server which runs on port 1234, the client 
is named selectchatclient.cpp 
             
***************************************************************************/ 


// max. Anzahl Clients 
// Max. number of clients 
#define MAX_CLIENTS 100 



// Der Standartwert für FD_SETSIZE ist 64, dieser kann aber verändert 
// werden indem man FD_SETSIZE auf einen anderen Wert setzt bevor man 
// winsock2.h includiert. 
// FD_SETSIZE auf die max. Anzahl Clients setzten 

// The default value of FD_SETSIZE is 64, which can be modified by 
// defining FD_SETSIZE to another value before including Winsock2.h. 
// set FD_SETSIZE to the max. number of clients 
#define FD_SETSIZE   MAX_CLIENTS 

// includes... 
#include <stdlib.h> 
#include <stdio.h> 
#include <windows.h> 
#include <winsock2.h> 
#include <conio.h> 

// Stellt eine Verbindung mit einem Client dar 
// Represents a connection with a Client 
struct Connection { 
   Connection() { 
      used=false; 
      socket=INVALID_SOCKET; 
   } 
   void set(SOCKET s, SOCKADDR_IN addr) { 
      this->socket=s; 
      this->addr=addr; 
      this->used=true; 
   } 
   void erase() { 
      this->used=false; 
      this->socket=INVALID_SOCKET; 
   } 
   bool used;   // connection benutzt ? / connection slot used ? 
   SOCKET socket; // socket 
   SOCKADDR_IN addr; // client addr 
}; 

// clients 
Connection clients[MAX_CLIENTS]; 

// Sucht den nächsten freien Platz im clients Array 
// -1 = kein platz frei 
// Searches the next free slot in the clients array 
// -1 = no free slot 
int getFreeClientSlot() { 
   for(int i=0;i<MAX_CLIENTS;i++) { 
      if(clients[i].used==false) 
         return i; 
   } 
   return -1; 
} 

// Sendet eine Nachricht an alle Clients 
// Send's a Message to all clients 
int sendToAllClients(char* msg) { 
   int rc,i; 
   for(i=0;i<MAX_CLIENTS;i++) { 
      if(!clients[i].used) 
         continue; 
      rc=send(clients[i].socket,msg,strlen(msg),0); 
      if(rc==SOCKET_ERROR) { 
         printf("Error: Sending to Client %d failed: %d\n",i,WSAGetLastError()); 
      } 
   } 
   return 0; 
} 

// Startet Winsock und gibt einige Infos zur Version aus 
// Starts winsock and dumps some infos about the version 
int startWinsock() { 
   int rc; 
   WSADATA wsaData; 
   rc=WSAStartup(MAKEWORD(2,0),&wsaData); 
   printf("Return Code: %d\n",rc); 
   if(rc==SOCKET_ERROR) { 
      printf("Error, exiting!\n"); 
      return rc; 
   } 
   printf("Winsock started:\n"); 
   printf("Version: %d.%d\n",LOBYTE(wsaData.wVersion),HIBYTE(wsaData.wVersion)); 
   printf("High Version: %d.%d\n",LOBYTE(wsaData.wHighVersion),HIBYTE(wsaData.wHighVersion)); 
   printf("Description: %s\n",wsaData.szDescription); 
   printf("System Status: %s\n",wsaData.szSystemStatus); 
   return 0; 
} 

// main... 
int main() { 
   // SOCKET welcher neue Verbindungen annimmt 
   // SOCKET which accepts new connections 
   SOCKET acceptSocket; 
   SOCKADDR_IN addr; 
   int rc,addrsize=sizeof(SOCKADDR_IN); 
   unsigned int i,j; 
   // fd_set 
   fd_set fdSetRead; 
   // timout für select() / timeout for select() 
   timeval selectTimeout; 
   // temporär benutz für neue verbindungen 
   // temporary used for new connections 
   Connection newConnection; 
   // buffer 
   char buf[1024]; 

   // clients array leeren / clear clients array 
   memset(clients,0x0,sizeof(Connection)*MAX_CLIENTS); 

   // start winsock 
   rc=startWinsock(); 
   if(rc==SOCKET_ERROR) 
      return 1; 

   // socket erstellen / create socket 
   acceptSocket=socket(PF_INET,SOCK_STREAM,0); 
   if(acceptSocket==INVALID_SOCKET) { 
      printf("Error, cannot create socket: %d\n",WSAGetLastError()); 
      return 1; 
   } 

   // sockt an port 1234 binden / bind socket to port 1234 
   memset(&addr,0,sizeof(SOCKADDR_IN)); 
   addr.sin_family=AF_INET; 
   addr.sin_port=htons(1234); 
   addr.sin_addr.s_addr=ADDR_ANY; 
   rc=bind(acceptSocket,(SOCKADDR*)&addr,sizeof(SOCKADDR_IN)); 
    if(rc==SOCKET_ERROR) { 
      printf("Error, bind() failed: %d\n",WSAGetLastError()); 
      return 1; 
   } 

   // auf verbindungen warten / listen for connections 
   rc=listen(acceptSocket,10); 
   if(rc==SOCKET_ERROR) { 
      printf("Error,listen() failed: %d\n",WSAGetLastError()); 
      return 1; 
   } 


   // 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 accept is guaranteed to 
   // complete without blocking. 
    
   while(1) { 

      // fd_set leeren / clear fd_set 
      FD_ZERO(&fdSetRead); 
       
      // den socket welcher verbindungen annimmt hinzufügen 
      // add the SOCKET which accepts new connections 
       
      FD_SET(acceptSocket,&fdSetRead); 
      // alle clients hinzufügen 
      // add all clients 
      for(i=0;i<MAX_CLIENTS;i++) { 
         if(clients[i].used) 
            FD_SET(clients[i].socket,&fdSetRead); 
      } 

      // warten bis irgend ein socket bereit ist, wenn timout NULL ist kehrt select() 
      // erst zurück wenn ein socket bereit ist, select() blockt also in diesem falle 
      // wait until any socket is ready (timeout = NULL, block until one socket is ready) 
      rc=select(0,&fdSetRead,NULL,NULL,NULL); 

      // abbrechen bei einem fehler 
      // break on error 
      if(rc<1) 
         break; 

      printf("select() returned %d ready sockets\n",rc); 
       
      for(i=0;i<fdSetRead.fd_count;i++) { 
       
         // acceptSocket ? 
         if(fdSetRead.fd_array[i]==acceptSocket) { 
            // verbindung annehmen / accept new connection 
            newConnection.socket=accept(acceptSocket,(SOCKADDR*)&newConnection.addr,&addrsize); 
            rc=getFreeClientSlot(); 
            if(rc==-1) { 
               printf("Cannot accept new clients\n"); 
               continue; 
            } 
            // zu den clients hinzufügen 
            // add to clients 
            clients[rc]=newConnection; 
            clients[rc].used=true; 
            printf("New Client accepted from %s\n",inet_ntoa(newConnection.addr.sin_addr)); 
            continue; 
         } 
          
         // ein client ? 
         // a client ? 
         for(j=0;j<MAX_CLIENTS;j++) { 
            if(!clients[j].used) 
               continue; 

            if(clients[j].socket==fdSetRead.fd_array[i]) { 
               rc=recv(clients[j].socket,buf,1023,0); 
               buf[rc]='\0'; 
               // rc==0 => client hat die verbindung beendet 
               // rc==0 => client closed connection 
               if(rc==0) { 
                  printf("Client %d (%s): closed connection\n",j,inet_ntoa(clients[j].addr.sin_addr)); 
                  closesocket(clients[j].socket); 
                  clients[j].erase(); 
                  continue; 
               // rc==SOCKET_ERROR => fehler, verbindung beenden! 
               // rc==SOCKET_ERROR => error, close connection! 
               } else if(rc==SOCKET_ERROR) { 
                  printf("Client %d (%s): Error %d\n",j,inet_ntoa(clients[j].addr.sin_addr),WSAGetLastError()); 
                    printf("Client %d (%s): Server aborts connection\n",j,inet_ntoa(clients[j].addr.sin_addr)); 
                  closesocket(clients[j].socket); 
                  clients[j].erase(); 
                  continue; 
               // daten empfangen und an alle clients senden 
               // receive data and send it to all clients 
               } else { 
                  printf("Client %d (%s): received '%s' \n",j,inet_ntoa(clients[j].addr.sin_addr),buf); 
                  sendToAllClients(buf); 
               } 
            } 
         } 
      } 
   } 

   // aufräumen 
   // cleanup 
   closesocket(acceptSocket); 
   WSACleanup(); 
   printf("Server shutdown, press any key to exit\n"); 
   getch(); 
}
 
Zuletzt bearbeitet:
Ok, haben un herrausgefunden, das das wohl doch nur ein reienr windows code ist, da allein 3 biblitehken nur für win giebt...

aber was ist mit diesem code hier:
http://www.zotteljedi.de/doc/socket-tipps/code_server.html

Der erzeugt foldendes beim compilieren:
root@idify-m:/home/greenrover# gcc ./selectchatsrv.cpp

./selectchatsrv.cpp: In function »int main()«:
./selectchatsrv.cpp:58: Fehler: ungültige Umwandlung von »int*« in »socklen_t*«
./selectchatsrv.cpp:58: Fehler: Argument 3 von »int accept(int, sockaddr*, socklen_t*)« wird initialisiert

Doch leider versteheh ich diese Meldung kein Stück.
 
Zurück