====== تابع ()accept ======
بعد از فراخوانی [[listen]] نوبت به فراخوانی [[accept]] میرسد تا به ازای هر connection جدید یک file descriptor جدید برای خواندن و نوشتن در آن connection ایجاد کند و اطلاعات مربوط به connection جدید را در یک struct sockaddr_storage برگرداند ( که درواقع cast شده است به struct sockaddr ) :
#include
#include
int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
نکته : [[accept]] از نوع blocking است.
مثال [[accept]] در وضعیت dual-stack :
#include
#include
#include
#include
#include
#include
#include
#include
#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