serwer ma przyjmować tylko dwa połączenia

0

Witam
mam kod:

#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdlib.h>
#include<time.h> 
#include <unistd.h>
#include <stdio.h>
#include<errno.h>
#include <sys/wait.h>
#include <err.h>

#define NR_PROC 2
#define MAXLINE 4091 

int SERVER, gnz, port, i;
struct sockaddr_in adres;
time_t ticks; // zmienna do czasu
pid_t pid;
char buff[MAXLINE]; 




void zakoncz()
  {
  close(SERVER);
  printf("Serwer wylaczony\n"); 
  exit(0);
  }

void polecenie(void)
  {
 char buf[4];
 
 int l;
while ((i=read(gnz,buf,10))>0)  //10 znakow bo \r\n,liczenie od 1
 {
   if (l=strncmp(buf,"dupa",4)==0)  //porownanie 4 bajtow z kazdego lancucha
   {
    write(gnz, "dupa wielka jest\n",38);
    close(gnz);
   }
   else if (l=strncmp(buf,"czas",4)==0)  //  POLECENIE CZAS
   {

    ticks=time(NULL);
    snprintf(buff, sizeof(buff), "Aktualny czas  to:  %.24s\r\n", ctime (&ticks));
    write(gnz, buff, strlen(buff));
    close(gnz);
   }

   else
    write(gnz, "Blad\n", 6);

 }  
     close(gnz);
    printf("Polaczenie z %s:%d - zerwane \n",inet_ntoa(adres.sin_addr), ntohs(adres.sin_port)); //adres klienta, port efemeryczny

   exit(1);
 
 }

int main(int argc, char** argv)
{
  signal(SIGCLD,SIG_IGN);
  signal(SIGINT,zakoncz);
  
  if (argc>1) //Numer portu wprowadzony jako argument, w przeciwnym wypadku uruchomnienie na porcie 3333
  port=atoi(argv[1]);
   else  
  port=3333;

  bzero((char *)&adres,sizeof(adres));
  adres.sin_family=AF_INET;
  adres.sin_addr.s_addr=INADDR_ANY; //przypisuj do gniazda serwera domyslny adres IP 
  adres.sin_port=htons(port);

  SERVER=socket(AF_INET,SOCK_STREAM,0);
  if (SERVER==-1)
  {
   perror("BLAD podczas tworzenia deskryptora gniazda!");
   return 1;
  }
  
  if (bind(SERVER,(struct sockaddr*)&adres,sizeof(adres)))
  {
   perror("BLAD w dowiazaniu numeru portu do serwera!");
   return 1;
  } 
if (listen(SERVER,3))
  {
   perror("BLAD podczas tworzenia kolejki polaczen");
   return 1;
  }

  printf("\nSerwer Uruchomiony\n");  

 for (;;)
  { 
    i=sizeof(adres);
    gnz=accept(SERVER, (struct sockaddr*)&adres,&i);
    printf("Nawiazano polaczenie od %s:%d\n",inet_ntoa(adres.sin_addr), ntohs(adres.sin_port));
    

  
    switch (pid=fork())

    {
    case 0 : close(SERVER); 
 printf ("Moj PID... %d\n", getpid());
    polecenie();
    return 0;//
    
for (i = 1; i <= NR_PROC; i++) 
    if (wait(0) == -1)
  

 return 0;//
    case -1: perror("Blad podczas tworzenia procesu");
    exit(1);
    default : close(gnz);  

  }
 }  
}

i nie moge zrealizowac jednego z problemow, a mianowicie zeby Serwer przyjmował tylko dwa połączenia jednocześnie.
Przy następnych ma zwracać klientowi, że połączenie nie może zostać w tej chwili obsłużone., jak widac zaczołem modzić ale nie wychodzi. Proszę o pomoc

0

Kod wewnątrz switch pomiędzy dwoma „return 0;//” nigdy się nie wykona.

Poza tym deklarujesz buf w funkcji polecenie jako czteroznakowy a czytasz 10, to nie jest dobry pomysł...
(to oczywiści uwaga bez związku z tematem)

IMVHO powinieneś zacząć liczyć uruchomionych potomków i w tym celu nie ignorować SIGCHLD, ale go przechwytywać i zmniejszać licznik o 1, a zwiakszać go po pomyslnym uruchomieniu:

static volatile int threads = 0;

void SIGCHLD_handler(int)
{
  int status;
  wait(&status);
  if(threads) threads--;
}

i potem wewnątrz main:

/*...*/
if (threads <= MAX) switch(fork()) { /*...*/ default: threads++; close(gnz); break; }
else { write(gnz, "Sorry, serwer przeciążony, spróbuj ponownie\n", ...); close(gnz); }

oczywiście można to zrobić na masę innych sposobów</cpp>

0

dzięki wielkie za pomoc, teraz działa jak trzeba [browar]

0

witam,
a czy mógłbym CIe prosić o cały kod albo gdzie to wkleić ? wklejam to i nie działa :( ciagle jakies bledy :(

1 użytkowników online, w tym zalogowanych: 0, gości: 1