CodeBlanks Logo Icon CodeBlanks

listen ve accept

  • C kursu
  • İleri seviye
  • Ders 27/83
  • 5 dk

listen ve accept ile bağlantı kabul etmeyi öğrenirsin.

listen ve accept

listen(fd, backlog), soketi pasif dinleme kipine alır. backlog, bekleyen bağlantı kuyruğunun uzunluğudur; genelde 5 verilir. Bundan sonra soket bağlantı kabul etmeye hazırdır.

accept(fd, NULL, NULL), gelen bir bağlantıyı kabul eder ve yeni bir tanıtıcı döndürür. Orijinal soket dinlemeye devam eder; yeni tanıtıcı istemciyle iletişim içindir. accept bağlantı gelene kadar bekler. connect ile istemci bağlanır; ayrıntısı sonraki derste.

Bağlantı kabulu

Sunucu accept'i çağırdığında, bir istemci connect ile bağlanana kadar bekler. Bağlantı geldiğinde accept yeni bir tanıtıcı döndürür.

Bu tanıtıcı üzerinden send ve recv ile veri alışverişi yapılır. Test için sunucu ve istemciyi aynı programda fork ile çalıştırabilirsin: ebeveyn dinler, çocuk bağlanır. Böylece sıralama garanti altındadır ve çıktı deterministik olur.

Uygulama Bağlantı kabul et

Soket oluştur, bind ve listen(listen_fd, 1) çağır. fork() ile çocuk oluştur; çocukta connect(cfd, (struct sockaddr *)&addr, sizeof(addr)). Ebeveynde int client_fd = accept(listen_fd, NULL, NULL); ve printf("kabul edildi\n");. Yol /tmp/cb_l.sock olsun.

Başlangıç kodu

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

// soket oluştur, bind ve listen çağır
// fork ile çocuk oluştur, çocuk connect yapsın
// ebeveyn accept ile kabul et ve yazdır

int main(void) {
    return 0;
}

Örnek çözüm

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

int main(void) {
    int listen_fd = socket(AF_UNIX, SOCK_STREAM, 0);
    struct sockaddr_un addr;
    memset(&addr, 0, sizeof(addr));
    addr.sun_family = AF_UNIX;
    strncpy(addr.sun_path, "/tmp/cb_l.sock", sizeof(addr.sun_path) - 1);
    unlink("/tmp/cb_l.sock");
    bind(listen_fd, (struct sockaddr *)&addr, sizeof(addr));
    listen(listen_fd, 1);
    pid_t pid = fork();
    if (pid == 0) {
        int cfd = socket(AF_UNIX, SOCK_STREAM, 0);
        connect(cfd, (struct sockaddr *)&addr, sizeof(addr));
        close(cfd);
        _exit(0);
    }
    int client_fd = accept(listen_fd, NULL, NULL);
    printf("kabul edildi\n");
    close(client_fd);
    close(listen_fd);
    unlink("/tmp/cb_l.sock");
    return 0;
}

Beklenen çıktı

kabul edildi

Soru ve cevaplar

Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.

1 listen çağrısı

Soru
listen(fd, ____);
Cevap
listen(fd, 5);

Açıklama: backlog 5, bekleme kuyruğu uzunluğudur.

2 Dinleme adımlarını eşle

Kavram Anlamı
listen Dinlemeye başlar
accept Bağlantı kabul eder
backlog Kuyruk uzunluğu
fork Süreç oluşturur

3 accept çağrıldığında ne döner?

  • Eski tanıtıcı
  • Bayt sayısı
  • Yeni tanıtıcı Doğru cevap
  • Adres yapısı

Açıklama: accept, istemci için yeni bir tanıtıcı döndürür.

İleri seviye bölümündeki tüm dersler