====== تابع ()socket ====== از تابع ()socket برای دریافت یک file descriptor جهت ارتباط با شبکه یا پروسس های دیگر، استفاده میشود. // man 2 socket #include #include sockfd = socket(int socket_family, int socket_type, int protocol); بهتر است تمام ورودی های تابع ()socket از طریق [[getaddrinfo]] آماده شود. درواقع domain همان rp->ai_family و type همان rp->ai_socktype و protocol همان rp->ai_protocol است. باید تک تک استراکچر های linked-listی که [[getaddrinfo]] برگردانده بررسی شود تا بالاخره بتوانیم هم از طریق تابع ()socket یک file descriptor بگیریم هم از طریق [[bind]] به port متصل شویم. مثال برای گرفتن file descriptor توسط تابع ()socket با کنترل تک تک استراکچرهای linked-list آماده شده توسط [[getaddrinfo]] : // socket.c // gcc -std=c99 -Wall -Wextra -Werror -pedantic -o socket socket.c #define _POSIX_C_SOURCE 200112L #include #include #include #include #include #include #include #include #define handle_error(msg) \ do { perror(msg); exit(EXIT_FAILURE); } while (0) #define PORT "3440" int main() { int sockfd, errcode; struct addrinfo hints, *res, *rp; char *ipver, ipstr[INET6_ADDRSTRLEN]; void *addr; memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_DGRAM; hints.ai_flags = AI_PASSIVE; /* For wildcard IP address */ errcode = getaddrinfo(NULL, PORT, &hints, &res); if (errcode != 0) { fprintf(stderr, "getaddrinfo(): %s\n", gai_strerror(errcode)); 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) { handle_error("socket() error"); continue; } if (rp->ai_family == AF_INET) { ipver = "IPv4"; addr = &(((struct sockaddr_in*)(rp->ai_addr))->sin_addr); } else { ipver = "IPv6"; addr = &(((struct sockaddr_in6*)(rp->ai_addr))->sin6_addr); } inet_ntop(rp->ai_family, addr, ipstr, sizeof ipstr); fprintf(stdout, "I got an %s socket for %s = %d\n", ipver, ipstr, sockfd); close(sockfd); } freeaddrinfo(res); return 0; } خروجی I got an IPv4 socket for 0.0.0.0 = 3 I got an IPv6 socket for :: = 3