Linux Sistem Programlama
  • Kapak
  • Önsöz
  • Sistem Programlamaya Giriş
    • Tarihçe
    • Standartlar
    • Sistem Çağrıları
    • API ve ABI
  • Linux Çekirdeği
  • Kabuk
  • Dosya Sistemi
  • Kullanıcı, Grup ve Erişim Yetkileri
  • Process Kavramı
  • Dosya İşlemleri
  • IO Modelleri
    • Senkron IO
    • Asenkron IO
  • Sinyaller
    • Temel Kavramlar
    • Sinyal Yakalama ve Gönderme
    • Signal-Safe Kavramı
    • Sinyal Kümeleri
    • Sinyal Bloklama
    • Sinyal İle Birlikte Veri Gönderimi
    • Sinyal ve Core Dump
    • RealTime Sinyaller
    • File Descriptor Üzerinden Sinyal İşleme
    • Genel Değerlendirme
  • Thread Kullanımı
    • Thread Oluşturma
    • Thread Türleri
    • Thread Sonlandırma
    • Mutex Kullanımı
    • SpinLock & Mutex Karşılaştırması
    • Futex
  • Semafor Kullanımı
    • Semafor ve Mutex Karşılaştırması
    • Semafor Türleri
    • Semafor Operasyonları
  • Shared Memory Kullanımı
  • Memory Mapped IO
  • Soket Kullanımı
    • Soket API
    • TCP Soketleri
    • UDP Soketleri
    • UNIX Soketleri
    • Birden Çok İstemciyle Çalışma
  • Timer Kullanımı
    • Basit Timer Yapıları
    • POSIX Timer API
    • Event Loop İçinde Kullanım
  • Daemon Oluşturma
  • Capabilities API
  • Paylaşımlı Kütüphaneler
    • Kütüphane Gereksinimi
    • Statik Kütüphaneler
    • Kod Referanslarının Ele Alınması
    • Paylaşımlı Kütüphanelerin Oluşturulması
    • Dinamik Yükleme
    • Derleme Zamanında Kütüphanelerin Aranması
    • Çalışma Zamanında Kütüphanelerin Aranması
    • Statik ve Dinamik Kütüphanelerin Beraber Kullanılması
    • Versiyon Yönetimi
  • Process'ler Arası Haberleşme
  • Memory Allocation
  • Memory Barriers
  • Hata Ayıklama Yöntemleri
    • GNU Debugger
    • Strace
  • GNU Build Sistemi Araçları
    • Make
    • Autoconf, Automake
  • Ek Bölümler
    • Derleyici Optimizasyonları
    • Clang ve LLVM
    • İçsel ve Anonim Fonksiyonlar
      • İçsel Fonksiyonlar
      • Anonim Fonksiyonlar
    • FreeTDS ile SqlServer Bağlantısı
  • Kaynak Dosyalar
Powered by GitBook
On this page

Was this helpful?

  1. Soket Kullanımı

UNIX Soketleri

UNIX alan soketleri (UNIX domain socket), Internet soketlerinin aksine, yalnız aynı makina üzerindeki proseslerin haberleşmesine imkan tanımaktadır. Internet soketlerinde olduğu gibi TCP ve UDP üzerinden haberleşme sağlanabilir.

UNIX alan soketi oluşturmak için socket fonksiyonuna ilk argüman olarak AF_UNIX sembolik sabitini geçirmeliyiz. Alan soketleri dosya sisteminde bir giriş oluşturmakta ve buna ilişkin bir yol ifadesi (pathname) almaktadır. Alan soketlerinin adresleri sockaddr_un yapı türünde saklanmaktadır.

struct sockaddr_un {
    sa_family_t sun_family; // AF_UNIX
    char sun_path[108]; // Null karakter ile sonlandırılmış soket yol ismi
};

Soket bind edildiğinde dosya sisteminde sokete ilişkin bir giriş oluşturulacaktır. Aşağıdaki örneği çalıştırıp bu durumu gözleyebiliriz.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>

#define UNIXSOCKNAME "/tmp/unixsock"

int main() {
    int sfd;
    struct sockaddr_un addr;
    sfd = socket(AF_UNIX, SOCK_STREAM, 0);
    if (sfd == -1)
        return 1;

    memset(&addr, 0, sizeof(struct sockaddr_un));

    addr.sun_family = AF_UNIX;

    strncpy(addr.sun_path, UNIXSOCKNAME, sizeof(addr.sun_path) - 1);
    if (bind(sfd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un)) == -1)
        return 1;

    return 0;
}
$ gcc -oserver server.c

$ ./server

$ ls -l /tmp/unixsock
srwxrwxr-x 1 serkan serkan 0 Mar 25 17:24 /tmp/unixsock

ls çıktısının başındaki s karakteri dosyanın bir sokete ilişkin olduğunu göstermektedir.

Basit bir örnek üzerinden, stream soketlerini kullanarak, sunucu ve istemci haberleşmesine bakalım. İstemci klavyeden girilen yazıyı sunucuya göndermektedir.

server.c:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>

#define UNIXSOCKNAME "/tmp/unixsock"
#define BUF_SIZE 100
#define BACKLOG 5

int main() {
    struct sockaddr_un addr;
    int sfd, cfd;
    ssize_t numRead;
    char buf[BUF_SIZE];
    sfd = socket(AF_UNIX, SOCK_STREAM, 0);
    if (sfd == -1)
        return 1;

    unlink(UNIXSOCKNAME);

    memset(&addr, 0, sizeof(struct sockaddr_un));
    addr.sun_family = AF_UNIX;
    strncpy(addr.sun_path, UNIXSOCKNAME, sizeof(addr.sun_path) - 1);

    if (bind(sfd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un)) == -1)
        return 1;

    if (listen(sfd, BACKLOG) == -1)
        return 1;

    for (;;) {
        cfd = accept(sfd, NULL, NULL);
        if (cfd == -1)
            return 1;

        while ((numRead = read(cfd, buf, BUF_SIZE)) > 0) {
            if (write(1, buf, numRead) != numRead)
                return 1;
        }
        close(cfd);
    }
    return 0;
}

client.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>

#define UNIXSOCKNAME "/tmp/unixsock"
#define BUF_SIZE 100

int main()
{
    struct sockaddr_un addr;
    int sfd;
    ssize_t numRead;
    char buf[BUF_SIZE];
    sfd = socket(AF_UNIX, SOCK_STREAM, 0);
    if (sfd == -1)
        return 1;

    memset(&addr, 0, sizeof(struct sockaddr_un));
    addr.sun_family = AF_UNIX;
    strncpy(addr.sun_path, UNIXSOCKNAME, sizeof(addr.sun_path) - 1);

    if (connect(sfd, (struct sockaddr *) &addr, sizeof(struct sockaddr_un)) == -1)
        return 1;

    while ((numRead = read(0, buf, BUF_SIZE)) > 0) {
        if (write(sfd, buf, numRead) != numRead)
            return 1;
    }
}
$ gcc -oserver server.c
$ gcc -oclient client.c
PreviousUDP SoketleriNextBirden Çok İstemciyle Çalışma

Last updated 5 years ago

Was this helpful?