تابع ()bind

در هر server پس از گرفتن file descriptor از طریق تابع ()socket باید آن را به یک port متصل کنیم تا برای تابع ()listen آماده باشد. این کار توسط تابع ()bind انجام میشود.

#include <sys/types.h>
#include <sys/socket.h>
 
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);

تمام ورودی های تابع ()bind از طریق تابع ()getaddrinfo و تابع ()socket آماده میشود. sockfd همان file descriptor حاصل از تابع ()socket است و addr هم همان rp→ai_addr و addrlen هم همان rp→ai_addrlen است.باید تک تک استراکچر های linked-listی که تابع ()getaddrinfo برگردانده بررسی شود تا بالاخره بتوانیم هم از طریق تابع ()socket یک file descriptor بگیریم هم از طریق تابع ()bind به port متصل شویم.

مثال برای گرفتن file descriptor توسط تابع ()socket و اتصال به یک port از طریق تابع ()bind ، با کنترل تک تک استراکچرهای linked-list آماده شده توسط تابع ()getaddrinfo :

#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 handle_error(msg) \
    do { perror(msg); exit(EXIT_FAILURE); } while (0)
 
#define PORT "3440"
 
int main()
{
	int status;
	struct addrinfo hints, *res, *rp;
	int sockfd;
	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;
 
	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) {
			handle_error("socket() error");
			continue;
 		}
		status = bind(sockfd, rp->ai_addr, rp->ai_addrlen);
		if (status == 0)
			break;
		handle_error("bind() error");
		close(sockfd);
	}
 
	if (rp == NULL) {
		fprintf(stderr, "Could not bind\n");
		exit(EXIT_FAILURE);
	}
 
	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 and bind to %s = %d\n", ipver, ipstr, PORT ,sockfd);
 
	close(sockfd);
	freeaddrinfo(res);
 
	return 0;
}

خروجی

I got an IPv4 socket for 0.0.0.0 and bind to 3440 = 3