Bayt Akımlı Bağlantı Sunucusu Örneği
Önceki Soketlerin Bağlantılarla Kullanılması Sonraki
Bayt Akımlı Bağlantı Sunucusu Örneği
Sunucu tarafı daha karmaşıktır. Aynı anda ço sayıda istemcinin sunucuya bağlı kalmasını istediğimiz için, basitçe read veya recv işlevini çağırarak tek bir istemciden girdi beklemek doğru olmaz. Yapılması gereken şey select işlevini (Girdi ve Çıktının Beklenmesi) kullanarak açık olan bütün soketlerden girdi beklemektir. Bu sunucuya ilave bağlantı istekleriyle ilgilenme imkanı da verir.
Bu sunucu istemciden bir ileti aldığında ilgi çekecek hiç bir şey yapmaz. Dosya sonu durumunu algıladığında o istemci için soketi kapatır (bu aynı zamanda istemcinin de soketi kapatmasına neden olur).
Bu yazılım soket adresini ayarlamak için make_socket'i kullanır; bkz. İnternet Soketi Örneği.
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

#define PORT    5555
#define MAXMSG  512

int
read_from_client (int filedes)
{
  char buffer[MAXMSG];
  int nbytes;

  nbytes = read (filedes, buffer, MAXMSG);
  if (nbytes < 0)
    {
      /* Okuma hatası. */
      perror ("read");
      exit (EXIT_FAILURE);
    }
  else if (nbytes == 0)
    /* Sosya sonu. */
    return -1;
  else
    {
      /* Veri okundu. */
      fprintf (stderr, "Sunucu: gelen ileti: `%s'\n", buffer);
      return 0;
    }
}

int
main (void)
{
  extern int make_socket (uint16_t port);
  int sock;
  fd_set active_fd_set, read_fd_set;
  int i;
  struct sockaddr_in clientname;
  size_t size;

  /* Soketi oluşturalım ve bağlantıları kabul etmesi için ayarlayalım. */
  sock = make_socket (PORT);
  if (listen (sock, 1) < 0)
    {
      perror ("listen");
      exit (EXIT_FAILURE);
    }

  /* Etkin soketleri ilklendirelim. */
  FD_ZERO (&active_fd_set);
  FD_SET (sock, &active_fd_set);

  while (1)
    {
      /* Etkin soketlerden bilgi gelene kadar baskılayalım. */
      read_fd_set = active_fd_set;
      if (select (FD_SETSIZE, &read_fd_set, NULL, NULL, NULL) < 0)
        {
          perror ("select");
          exit (EXIT_FAILURE);
        }

      /* Girdi bekleyerek bütün soketleri hizmete sokalım. */
      for (i = 0; i < FD_SETSIZE; ++i)
        if (FD_ISSET (i, &read_fd_set))
          {
            if (i == sock)
              {
                /* Dinlenen sokette bağlantı isteği var. */
                int new;
                size = sizeof (clientname);
                new = accept (sock,
                              (struct sockaddr *) &clientname,
                              &size);
                if (new < 0)
                  {
                    perror ("accept");
                    exit (EXIT_FAILURE);
                  }
                fprintf (stderr,
                          "Sunucu: Konak %s, %hd. portundan baglaniyor\n",
                          inet_ntoa (clientname.sin_addr),
                          ntohs (clientname.sin_port));
                FD_SET (new, &active_fd_set);
              }
            else
              {
                /* Bağlı olan sokete veri ulaşıyor. */
                if (read_from_client (i) < 0)
                  {
                    close (i);
                    FD_CLR (i, &active_fd_set);
                  }
              }
          }
    }
}
Önceki Üst Ana Başlık Sonraki
Bayt Akımlı Soket Örneği Başlangıç Bantdışı Veri Aktarımı
Bir Linux Kitaplığı Sayfası