تابع ()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.
