네트워크 프로 그래 밍 에서 4 개의 중요 한 주소 데이터 구조
16110 단어 데이터 구조
1 struct sockaddr_in { 2 sa_family_t sin_family; /* AF_INET */
3 in_port_t sin_port; /* Port number. */
4 struct in_addr sin_addr; /* Internet address. */
5
6 /* Pad to size of `struct sockaddr'. */
7 unsigned char sin_zero[sizeof (struct sockaddr) -
8 sizeof (sa_family_t) -
9 sizeof (in_port_t) -
10 sizeof (struct in_addr)]; 11 }; 12 typedef uint32_t in_addr_t; 13 struct in_addr { 14 in_addr_t s_addr; /* IPv4 address */
15 };
2. IPv6: struct sockaddr_바이트
1 struct sockaddr_in6 { 2 sa_family_t sin6_family; /* AF_INET6 */
3 in_port_t sin6_port; /* Transport layer port # */
4 uint32_t sin6_flowinfo; /* IPv6 flow information */
5 struct in6_addr sin6_addr; /* IPv6 address */
6 uint32_t sin6_scope_id; /* IPv6 scope-id */
7 }; 8 struct in6_addr { 9 union { 10 uint8_t u6_addr8[16]; 11 uint16_t u6_addr16[8]; 12 uint32_t u6_addr32[4]; 13 } in6_u; 14
15 #define s6_addr in6_u.u6_addr8
16 #define s6_addr16 in6_u.u6_addr16
17 #define s6_addr32 in6_u.u6_addr32
18 };
3. 유 니 버 설 구조 체 1: struct sockaddr, 16 바이트
1 struct sockaddr { 2 sa_family_t sa_family; /* Address family */
3 char sa_data[14]; /* protocol-specific address */
4 };
4. 통용 구조 체 2: struct sockaddrstorage, 128 바이트
1 /* Structure large enough to hold any socket address
2 (with the historical exception of AF_UNIX). 128 bytes reserved. */
3
4 #if ULONG_MAX > 0xffffffff
5 # define __ss_aligntype __uint64_t
6 #else
7 # define __ss_aligntype __uint32_t
8 #endif
9 #define _SS_SIZE 128
10 #define _SS_PADSIZE (_SS_SIZE - (2 * sizeof (__ss_aligntype)))
11
12 struct sockaddr_storage
13 {
14 sa_family_t ss_family; /* Address family */
15 __ss_aligntype __ss_align; /* Force desired alignment. */
16 char __ss_padding[_SS_PADSIZE];
17 };
왜 통용 구조 체 가 있 고 왜 두 개의 통용 구조 체 가 있 습 니까?다음은 순 전 히 개인 적 인 견해 다.
네트워크 통신 에는 IPv 4, IPv 6, IPX, X. 25, AX. 25... (socket 함수 의 domain 매개 변 수 는 프로 토 콜 족 을 나타 낸다).네트워크 프로 그래 밍 에서 사용 되 지 않 는 것 은 어떤 프로 토 콜 입 니까? 같은 socket API 를 사용 합 니 다. 모든 프로 토 콜 은 네트워크 주소 의 구조 체 가 다 릅 니 다. 예 를 들 어 IPv 4 는 struct sockaddr 입 니 다.in, IPv 6 는 struct sockaddrin6. 따라서 네트워크 주 소 를 나타 내 는 모든 구조 체 를 하나의 통용 되 는 구조 체 로 추상 화해 야 한다. 추상 화 된 구조 체 는 바로 struct sockaddr 이다.(구체 적 인 협의의 주소 구조 와 통용 되 는 주소 구조의 관 계 는 대상 을 대상 으로 프로 그래 밍 하 는 대상 과 클래스 의 관계 와 유사 하 다. 나 는 대상 을 대상 으로 프로 그래 밍 하 는 것 을 배 운 적 이 없다. 다만 이 두 가지 사상 이 약간 유사 하 다 는 것 을 어렴풋이 느 낄 뿐이다)
struct sockaddr 와 관련 된 sock API 는 다음 과 같 습 니 다.
1 /*application->kernel*/
2 int bind (int sockfd, struct sockaddr *my_addr, socklen_t addrlen); 3
4 int connect(int sockfd, const struct sockaddr *serv_addr, 5 socklen_t addrlen); 6
7 int sendto (int s, const void *msg, size_t len, int flags, 8 const struct sockaddr *to, socklen_t tolen); 9
10 /*kernel->application*/
11 int accept (int s, struct sockaddr *addr, socklen_t *addrlen); 12
13 int recvfrom (int s, void *buf, size_t len, int flags, 14 struct sockaddr *from, socklen_t *fromlen); 15
16 int getpeername(int s, struct sockaddr *name, socklen_t *namelen); 17 int getsockname(int s, struct sockaddr *name, socklen_t *namelen);
그런데 왜 struct sockaddrstorage 라 는 유 니 버 설 구조 체 는?
일반적인 주소 데이터 구조 로 서 그 크기 는 모든 구체 적 인 프로 토 콜 주소 구조 크기 의 최대 값 이 어야 합 니 다. 그러나 size of (struct sockaddr) = 16, size of (struct sockaddr in6) = 28, 분명히 struct sockaddr 라 는 통용 되 는 데이터 구조 hold 는 IPv 6 를 유지 하지 못 하기 때문에 struct sockaddrstorage 라 는 새로운 구 조 는 하늘 을 가로 질 러 나 왔 습 니 다. 크기 는 128 바이트 이 므 로 현재 프로 토 콜 의 주소 구 조 를 담 을 수 있 을 것 입 니 다.
다양한 프로 토 콜 과 관련 된 네트워크 프로 그래 밍 에서 struct sockaddrstorage 라 는 구조 체 는 통신 주 소 를 표시 하고 socket API 를 호출 할 때 struct sockaddrstorage 강제 형식 은 struct sockaddr 로 변환 되 고 주소 길 이 는 size of (struct sockaddr storage) 입 니 다.예:
1 struct sockaddr_storage addr; 2 /*
3 4 */
5 sendto (s, *msg, len, flags, (struct sockaddr *)&addr, sizeof(struct sockaddr_storage));
API 에 있 는 struct sockaddr 를 struct sockaddr 로 직접 바 꾸 지 않 는 이 유 를 물 어 볼 수도 있 습 니 다.storage?매번 쓸 때마다 유형 전환 을 강요 하 는 게 얼마나 귀 찮 은 데.
하나의 API 정의 후 인 자 는 바 꿀 수 없습니다. 그렇지 않 으 면 오래된 코드 가 실 행 될 수 없습니다.
처음부터 struct sockaddr 의 크기 를 크게 정의 하지 않 았 느 냐 는 질문 도 있 을 것 이다.
struct sockaddr 를 정의 할 때 IPv 4 시대 에 struct sockaddr 를 정의 하 는 사람 은 미래 에 IPv 6 의 탄생 을 예상 하지 못 했 기 때문에 struct sockaddr 를 struct sockaddr 와in 같은 크기.
IPv 4/IPv 6 혼합 프로 그래 밍 예시:
1 struct sockaddr_storage addr; 2 memset(&addr, 0, sizeof(struct sockaddr_storage)); 3 if (isIPv6 == TRUE) 4 { 5 struct sockaddr_in6 *addr_v6 = (struct sockaddr_in6 *)&addr; 6 addr_v6->sin6_family = AF_INET6; 7 addr_v6->sin6_port = 1234; 8 inet_pton(AF_INET6, “2001:3211::1”, &(addr_v6->sin6_addr)); 9 } 10 else
11 { 12 struct sockaddr_in *addr_v4 = (struct sockaddr_in *)&addr; 13 addr_v4->sin_family = AF_INET; 14 addr_v4->sin_port = 1234; 15 inet_aton(“192.168.1.228”, &(addr_v4->sin_addr)); 16 } 17
18 sendto(sock, buf, len, 0, (struct sockaddr *)&addr, sizeof(struct sockaddr_storage));
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
정수 반전Udemy 에서 공부 한 것을 중얼거린다 Chapter3【Integer Reversal】 (예) 문자열로 숫자를 반전 (toString, split, reverse, join) 인수의 수치 (n)가 0보다 위 또는 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.