ابزار کاربر

ابزار سایت


c-socket-programming:listen

تابع ()listen

در سرورهای tcp این تابع یک socket file descriptor را که از تابع ()socket به دست آمده و با تابع ()bind به یک پورت مربوط شده را به عنوان passive socket علامت میزند. یک passive socket نو عی سوکت است که برای قبول کانکشنهای client ها از تابع ()accept استفاده خواهد کرد.

#include <sys/types.h>
#include <sys/socket.h>
 
int listen(int sockfd, int backlog);

پارامتر backlog مشخص میکند چه تعدادی درخواست در صف منتظر فراخوانی تابع ()accept هستند. بعد از کرنل 2.2 این تعداد نشان دهنده تعداد کانکشن های established شده ای است که در صف منتظرند.

ماکزیمم کانکشن هایی که هنوز established نشده اند در proc/sys/net/ipv4/tcp_max_syn_backlog/ مشخص می شود. اگر syncookies در کرنل enable باشد این مقدار بدون ماکزیمم است.

اگر مقدار blacklog بیشتر از مقدار proc/sys/net/core/somaxconn/ باشد به مقدار somaxconn تبدیل میشود. از کرنل 5.4 به بعد این مقدار پیش فرض 4096 است که در گذشته 128 بوده.

مثال

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
 
#define handle_error(msg) \
    do { perror(msg); exit(EXIT_FAILURE); } while(0)
 
#define PORT "3450"
#define BACKLOG 120
 
int main()
{
    int status, sockfd, option;
    struct addrinfo hints, *res, *rp;
 
    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = 0;
 
    status = getaddrinfo(NULL, PORT, &hints, &res);
    if (status != 0) {
        fprintf(stderr, "getaddrinfo(): %s\n", gai_strerror(status));
        exit(EXIT_FAILURE);
    }
 
    for (rp = res; rp != NULL; rp = rp->ai_next) {
 
        sockfd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
        if (sockfd == -1) {
            perror("socket() error");
            continue;
        }
 
        option = 1;
        status = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &option, sizeof(option));
        if (status == -1)
            handle_error("setsockopt() error");
 
        status = bind(sockfd, rp->ai_addr, rp->ai_addrlen);
        if (status == -1) {
            perror("bind() error");
            close(sockfd);
            continue; 
        }
 
        break;
    }
    freeaddrinfo(res);
 
    if (rp == NULL) {
        fprintf(stderr,"Server: failed to not bind\n");
        exit(EXIT_FAILURE);
    }
 
    status = listen(sockfd, BACKLOG);
    if (status == -1)
        handle_error("linsten() error");
 
    fprintf(stdout, "Listening started ... \n");
    fprintf(stdout, "You can check netstat for 60 seconds\n");
    sleep(60);
    fprintf(stdout, "End.\n");
 
    close(sockfd);
 
    return 0;
}

خروجی

Listening started ... 
You can check netstat for 60 seconds
End.
c-socket-programming/listen.txt · آخرین ویرایش: 2024/06/18 01:00 توسط pejman

به جز مواردی که ذکر می‌شود، مابقی محتویات ویکی تحت مجوز زیر می‌باشند: Public Domain
Public Domain Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki