Veri Paketi Soketleri
Önceki İstemci-Sunucu Mimarisi Sonraki
Veri Paketi Soketleri
Buraya dek yazılanları anladı iseniz çok fazla açıklamaya gerek yok, örnek programların kodunu inceleyerek kavrayabilirsiniz: talker.c ve listener.c..
listener programı bir makinada çalıştıktan sonra 4950 numaralı port üzerinden gelecek paketleri dinlemeye başlar. talker ise komut satırında belirteceğiniz bir makinanın 4950 numaralı portuna yine komut satırından yazdığınız mesajı bir veri paketi olarak yollar.
listener.c programının kaynak koduna bakalım:
/*
** listener.c -- a veri paketi soketi sunucusu örneği
*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define MYPORT 4950    // kullanıcıların bağlanacağı port

#define MAXBUFLEN 100

int main(void)
{
    int sockfd;
    struct sockaddr_in my_addr;    // adres bilgim
    struct sockaddr_in their_addr; // bağlananın adres bilgisi
    int addr_len, numbytes;
    char buf[MAXBUFLEN];

    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
        perror("socket");
        exit(1);
    }

    my_addr.sin_family = AF_INET;         // konak bayt sıralaması
    my_addr.sin_port = htons(MYPORT);     // short, ağ bayt sıralaması
    my_addr.sin_addr.s_addr = INADDR_ANY; // otomatik olarak IP'mi kullan
    memset(&(my_addr.sin_zero), '\0', 8); // kalanı sıfırla

    if (bind(sockfd, (struct sockaddr *)&my_addr,
                                          sizeof(struct sockaddr)) == -1) {
        perror("bind");
        exit(1);
    }

    addr_len = sizeof(struct sockaddr);
    if ((numbytes=recvfrom(sockfd,buf, MAXBUFLEN-1, 0,
                       (struct sockaddr *)&their_addr, &addr_len)) == -1) {
        perror("recvfrom");
        exit(1);
    }

    printf("got packet from %s\n",inet_ntoa(their_addr.sin_addr));
    printf("packet is %d bytes long\n",numbytes);
    buf[numbytes] = '\0';
    printf("packet contains \"%s\"\n",buf);

    close(sockfd);

    return 0;
} 
Dikkat edin ki socket() işlevini çağırırken SOCK_DGRAM kullandık. Ayrıca bu tür soketlerde listen() veya accept() işlevlerine ihtiyacımız yok. Bağlantısız veri paketi soketlerini kullanmanın güzel yanları da var gördüğünüz gibi!
Şimdi de sırada talker.c programının kaynak kodu var::
/*
** talker.c -- a datagram "client" demo
*/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

#define MYPORT 4950    // kullanıcıların bağlanacağı port

int main(int argc, char *argv[])
{
    int sockfd;
    struct sockaddr_in their_addr; // bağlananın adres bilgisi
    struct hostent *he;
    int numbytes;

    if (argc != 3) {
        fprintf(stderr,"usage: talker hostname message\n");
        exit(1);
    }

    if ((he=gethostbyname(argv[1])) == NULL) {  // konak bilgisini al
        perror("gethostbyname");
        exit(1);
    }

    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
        perror("socket");
        exit(1);
    }

    their_addr.sin_family = AF_INET;     // konak bayt sıralaması
    their_addr.sin_port = htons(MYPORT); // short, ağ bayt sıralaması
    their_addr.sin_addr = *((struct in_addr *)he->h_addr);
    memset(&(their_addr.sin_zero), '\0', 8); // kalanı sıfırla

    if ((numbytes=sendto(sockfd, argv[2], strlen(argv[2]), 0,
         (struct sockaddr *)&their_addr, sizeof(struct sockaddr))) == -1) {
        perror("sendto");
        exit(1);
    }

    printf("sent %d bytes to %s\n", numbytes,
                                           inet_ntoa(their_addr.sin_addr));

    close(sockfd);

    return 0;
} 
Hepsi bu kadar! Bir bilgisayarda listener programını derleyip çalıştırın ve başka bir bilgisayara geçip talker programını çalıştırın, birbirleri ile ne kadar güzel iletişim kurduklarını gözlemleyin!
Bu bölümü bitirmeden önce son bir ayrıntı: daha önce bağlantılı veri paketi soketlerinden bahsetmiştim. Madem veri paketi iletişimi ile ilgili örnek verdik o halde birkaç şey daha söylememe izin verin. Mesela talker connect() işlevini çağırıyor olsun ve listener'ın adresini belirtmiş olsun. O noktadan itibaren talker sadece ve sadece connect() ile belirlenen adresi kullanabilir. Bu yüzden sendto() ve recvfrom() kullanmanıza gerek kalmaz; send() ve recv() ile işinizi görebilirsiniz.
Önceki Üst Ana Başlık Sonraki
Basit Bir Veri Akış İstemcisi Başlangıç İleri Teknikler
Bir Linux Kitaplığı Sayfası