Domain Soketleri ve Internet Soketleri



Yüklə 181,98 Kb.
Pdf görüntüsü
səhifə6/7
tarix17.10.2017
ölçüsü181,98 Kb.
#5100
1   2   3   4   5   6   7

4.2. sunucu.c 

#include

#include

#include

#include

#include

#include

#define PORT 3333

#define LISTQUEUE 5

main(int argc, char *argv[]) {

  int sockfd, new_fd;

  struct sockaddr_in server_addr, client_addr;

  int client_size;

  char buffer[1024];

  printf("%s %d portu uzerinde calismaya basladi...\n\n",argv[0],PORT);

  if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {

    perror("socket");

    exit(1);

  }

  memset(&server_addr, 0, sizeof(server_addr));



  server_addr.sin_family = AF_INET;

  server_addr.sin_port = htons(PORT);

  server_addr.sin_addr.s_addr = INADDR_ANY;

  if(bind(sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) {

    perror("bind");

    exit(1);

  }

  if(listen(sockfd, LISTQUEUE) != 0) {



    perror("listen");

    exit(1);

  }

  while(1) {



    client_size = sizeof(struct sockaddr_in);

       if((new_fd=accept(sockfd,(struct   sockaddr*)&client_addr,&client_size))   ==

-1) {

      perror("accept");



      exit(1);

    }


    printf("%s sunucumuza baglandi...\n",inet_ntoa(client_addr.sin_addr));

    memset(&buffer, 0, sizeof(buffer));

    strcpy(buffer,"Merhaba ");

    strcat(buffer,(char *) inet_ntoa(client_addr.sin_addr));

    strcat(buffer," :)\n");

    if(send(new_fd,&buffer, strlen(buffer), 0) == -1) {

      perror("send");

      exit(1);

    }

    if(recv(new_fd,&buffer, strlen(buffer)-1, 0) == -1) {



      perror("recv");

      exit(1);

    }

    printf("Alinan yanit: %s\n", buffer);



    close(new_fd);

  }


  close(sockfd);

  return 0;

}



Evet.   İşte   harika   dünyaya   adım   attık   ve   "Merhaba"   dedik.   Bunu   ilk   denediğimde   gözlerime

inanamamıştım. Başka bir bilgisayardaki kişiye merhaba demiştim. O zamanlar chat programları bu

kadar populer değildi. Henüz mirc yokken, irc'a müptela olduğumuz günler. Bu gerçekten harika bir

şey.


Şimdi programımızı linux altında "GNU C Compiler" gcc ile nasıl derleyeceğimizi görelim.

cclub:~> gcc -o sunucu1 sunucu.c

Bu   komutla   sunucu.c   dosyasına   yazdığımız   kodları   derleyip   sunucu1   isimli   çalışabilir   dosyayı

ürettik. Bakalım neler oluyor:

cclub:~> ./sunucu1

./sunucu1 2222 portu uzerinde calismaya basladi...

193.140.168.54 sunucumuza baglandi...

Tahmin   edeceğiniz   gibi   bunlar   sunucunun   ekranına   yazanlar.   "193.140.168.54   sunucumuza

baglandi..."   mesajı,   ceng   hostundan   bağlantı   yapıldığında   ekrana   basılmıştır.   Peki   istemcinin

ekranına neler dönüyor:

ceng:~# telnet 193.140.168.77 2222 

Trying 193.140.168.77... 

Connected to 193.140.168.77. 

Escape character is '^]'. 

Merhaba 193.140.168.54 :)

Merhaba   193.140.168.54   :)   mesajı,   sunucu   tarafından  istemcimize  (telnet)   gönderilen   mesajdır.

Onun üstündeki mesajları merak etmeyin. Onların bizimle ilgisi yok. Telnet'in ürettiği mesajlardır.

Windows makineden "Başlat->Çalıştır" kullanarak aynı komutu verebilirsiniz.



5. İstemci Soket Programı

Şimdi istemci bir soket programın genel yapısına bakalım. Başlangıç aşamasında işlemler sunucu

program   ile   aynı   olacaktır.   Ancak   asıl   iş   yapılan   kısımda   hem   mimari,   hem   de   fonksiyonlar

değişeek. Çünkü bir taraf hizmet verme, öteki taraf ise hizmet alma durumunda olacaktır. Şimdi

geliştireceğimiz istemci yukardaki sunucu için geliştirilmemiştir. Bu programımız 3333 numaralı

portta   çalışsın.   Bu   istemci   program   için   bir   de   sunuu   program   yazdım.   Sunucu   programın

çalışmasını yukarıda anlattığımdan tekrar bu program için de anla. Bu programımız 3333 numaralı

portta   çalışsın.   Bu   istemci   program   için   bir   de   sunuu   program   yazdım.   Sunucu   programın

çalışmasını yukarıda anlattığımdan tekrar bu program için de anlatmayacağım. Doğrudan kodunu

vermekle yetineceğim.

Öncelikle port numaramızı belirleyelim:

#define PORT 3333

Sunucunun çalıştığı bilgisayar istemciye parametre olarak verilecek:

int main(int argc, char *argv[])

{

  if (argc != 2) {



    printf("Kullanimi : %s hostname ",argv[0]);

    exit(1);

  }

}



Sunucunun Belirlenmesi:

Parametre olarak alınan host ismini çözümlüyoruz. Adres yapısında olan server_addr değişkenine

PORT numarasını ve IP adresini yazıyoruz.

struct hostent *h_name;

if(argc > 1) {

  h_name = gethostbyname(argv[1]);

}

else {


  printf("Kullanimi: %s hostname ",argv[0]);

  exit(1);

}

bzero((char *) &serv_addr, sizeof(serv_addr));



serv_addr.sin_family = AF_INET;

serv_addr.sin_addr.s_addr = *(u_long *) h_name->h_addr;

serv_addr.sin_port = htons(PORT);

printf("Sunucu adresi: %s ",inet_ntoa(serv_addr.sin_addr));



Sunucuya Bağlanma:

Artık hizmetkarımıza, yani sunucumuza bağlanıp selam verme vakti geldi.

printf("Mesajinizi girin: ");

fgets(buf, sizeof(buf)+1, stdin);

if((send(sockfd, buf, sizeof(buf), 0)) <= 0) perror("send");

if((recv(sockfd, buf, sizeof(buf), 0)) <= 0) perror("recv");

printf("Sunucu'dan gelen mesaj: %s", buf);

shutdown(sockfd, 2);

close(sockfd);

Aynen sunucu programda olduğu gibi soket açtık. Soket türümüz yine SOCK_STREAM. Sonra

connect()fonksiyonunu   kullanarak   açtığımız   soket   üzerinden   bir   bağlantı   yaptık.   connect()

fonksiyonu sys/types.h başlık dosyasında aşağıdaki gibi tanımlanmıştır:

int connect(int s, const void *addr, int addrlen);

İlk parametre soket tanımlayıcısı, ikinci parametre bağlantı kurulacak sunucunun adres bilgilerini

içeren server_addr yapısı, son parametre ise adres yapısının boyutudur. Artık sunucumuzla aramızda

stream   bir   soket   bağlantısı   kurmuş   olduk.   İstemci   tarafında   connect()   yapıldığı   zaman,   sunucu

tarafında   accept()   yapılır.   Yani   yapılan   bağlantı   kabul   edilir.   Daha   önce   yazdığımız   sunucu

programdaki   accept()   işlemi,   telnet   programının   connect()   isteğini   karşılıyordu.   Şimdi   bizim

istemimiz bu isteği gönderecek. Dikkat ederseniz ilkel bir telnet programı yazıyoruz. 

Sunucuya Bilgi Gönderme:

Sonraki kısmı, anlaşılması açısından basit tuttum. Ekrandan bir mesaj alıp bunu send() fonksiyonu

ile sunucuya gönderiyoruz. Bu fonksiyon, dosyalara yazmak için kullandığımız write() fonksiyonu

gibidir. send() ile sokete veri gönderiyoruz. Soket sunucu ile bağlantılı olduğundan veri, sunucuya

ulaşır. Sunucu ise her send() isteğine recv() ile karşılık verir. send() yada recv() işlemleri her iki

tarafta da yapılabilir. Sunucudan gelen her send() isteğine karşı da istemci de bir recv() vardır.

Örneğin ftp programında karşılık send() ve recv() işlemleri vardır. Siz önce istemci tarafından 'get

dosya'   komutunu   göndererek   dosya   isteğinizi   belirtiyorsunuz.   Sunucu   bu   komutu   okuyup




Yüklə 181,98 Kb.

Dostları ilə paylaş:
1   2   3   4   5   6   7




Verilənlər bazası müəlliflik hüququ ilə müdafiə olunur ©genderi.org 2024
rəhbərliyinə müraciət

    Ana səhifə