ابزار کاربر

ابزار سایت


socket-programming:bind

این یک نگارش قدیمی از این مطلب است!


تابع ()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
socket-programming/bind.1718657915.txt.gz · آخرین ویرایش: 2024/06/18 00:28 توسط pejman

به جز مواردی که ذکر می‌شود، مابقی محتویات ویکی تحت مجوز زیر می‌باشند: Public Domain
Public Domain Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki