socket-programming:accept
این یک نگارش قدیمی از این مطلب است!
تابع ()accept
بعد از فراخوانی listen نوبت به فراخوانی accept میرسد تا به ازای هر connection جدید یک file descriptor جدید برای خواندن و نوشتن در آن connection ایجاد کند و اطلاعات مربوط به connection جدید را در یک struct sockaddr_storage برگرداند ( که درواقع cast شده است به struct sockaddr ) :
#include <sys/types.h> #include <sys/socket.h> int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
نکته : accept از نوع blocking است.
مثال accept در وضعیت dual-stack :
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/socket.h> #include <netdb.h> #include <arpa/inet.h> #define PORT "3450" #define BACKLOG 120 int main() { int status, sockfd, clientfd, sockopt; struct addrinfo hints, *res, *rp; struct sockaddr_storage clientaddr; socklen_t addrlen; memset(&hints, 0, sizeof(hints)); hints.ai_flags = AI_PASSIVE; hints.ai_family = AF_INET6; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = 0; status = getaddrinfo(NULL, PORT, &hints, &res); if (status != 0) { fprintf(stderr, "getaddrinfo() error: %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; } sockopt = 1; status = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &sockopt, sizeof(sockopt)); if (status == -1) { perror("setsockopt() error"); exit(EXIT_FAILURE); } sockopt = 0; status = setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY, &sockopt, sizeof(sockopt)); if (status == -1) { perror("setsockopt() error"); exit(EXIT_FAILURE); } status = bind(sockfd, rp->ai_addr, rp->ai_addrlen); if (status == -1) { perror("bind() error"); continue; } break; } freeaddrinfo(res); if (rp == NULL) { fprintf(stderr, "Server: Failed to bind()\n"); exit(EXIT_FAILURE); } status = listen(sockfd, BACKLOG); if (status == -1) { perror("listen() error"); exit(EXIT_FAILURE); } printf("Server: waiting for connections...\n"); addrlen = sizeof(clientaddr); clientfd = accept(sockfd, (struct sockaddr*)&clientaddr, &addrlen); void *addr; char *ipver; char ipstr[INET6_ADDRSTRLEN]; struct sockaddr *sa = (struct sockaddr*)&clientaddr; if (sa->sa_family == AF_INET) { ipver = "IPv4"; addr = &(((struct sockaddr_in *)sa)->sin_addr); } else { ipver = "IPv6"; addr = &(((struct sockaddr_in6 *)sa)->sin6_addr); } inet_ntop(sa->sa_family, addr, ipstr, sizeof(ipstr)); printf("Server: Got an %s connection from %s\n", ipver, ipstr); close(clientfd); close(sockfd); return 0; }
کلاینت
telnet 127.0.0.1 3450
خروجی سرور
Server: waiting for connections... Server: Got an IPv6 connection from ::ffff:127.0.0.1
socket-programming/accept.1718657962.txt.gz · آخرین ویرایش: 2024/06/18 00:29 توسط pejman
