bind()를 호출할 때 sockaddr_in을 sockaddr에 캐스팅하는 이유는 무엇입니까?
bind() 함수는 에 대한 포인터를 받아들입니다.sockaddr
하지만 내가 본 모든 예에서sockaddr_in
대신 구조체가 사용되며, 다음으로 캐스트됩니다.sockaddr
:
struct sockaddr_in name;
...
if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0)
...
왜 그런지 이해가 안 돼요?sockaddr_in
사용되는 구조입니다.그냥 준비해서 합격하는 게 어때?sockaddr
?
그냥 관례인가요?
이 질문에 매우 관련이 있는지는 모르겠지만, 저는 타이프 캐스트를 더 이해하기 쉽게 만들 수 있는 몇 가지 추가 정보를 제공하고 싶습니다.C
그런 타이프 캐스트를 보면 혼란스러워진다.
사용하고 있다macOS
그래서 저는 제 시스템에서 헤더 파일을 기반으로 예를 들고 있습니다.
struct sockaddr
는 다음과 같이 정의됩니다.
struct sockaddr {
__uint8_t sa_len; /* total length */
sa_family_t sa_family; /* [XSI] address family */
char sa_data[14]; /* [XSI] addr value (actually larger) */
};
struct sockaddr_in
는 다음과 같이 정의됩니다.
struct sockaddr_in {
__uint8_t sin_len;
sa_family_t sin_family;
in_port_t sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
기본부터 시작하는 포인터에는 주소만 포함됩니다.그렇게struct sockaddr *
그리고.struct sockaddr_in *
거의 비슷합니다.둘 다 주소만 저장해요유일하게 관련된 차이는 컴파일러가 오브젝트를 처리하는 방법입니다.
그래서 당신이 말할 때(struct sockaddr *) &name
컴파일러를 속여서 이 주소가 다음 주소를 가리키고 있음을 알립니다.struct sockaddr
유형.
포인터가 현재 위치를 가리키고 있다고 가정해 봅시다.1000
. 만약struct sockaddr *
이 주소를 저장합니다.메모리를 고려합니다.1000
로.sizeof(struct sockaddr)
구조 정의에 따른 부재 보유.한다면struct sockaddr_in *
메모리라고 간주되는 같은 주소를 저장합니다.1000
로.sizeof(struct sockaddr_in)
.
그 포인터를 타이프캐스트하면, 같은 바이트의 시퀀스를 최대sizeof(struct sockaddr)
.
struct sockaddr *a = &name; // consider &name = 1000
액세스 할 수 있는 경우a->sa_len
컴파일러는 로케이션에서 접근합니다.1000
로.sizeof(__uint8_t)
같은 바이트 크기입니다.sockaddr_in
같은 바이트 시퀀스에 액세스 할 수 있습니다.
같은 패턴은sa_family
.
그 후 에는 14바이트 문자 배열이 있습니다.struct sockaddr
데이터를 저장합니다.in_port_t sin_port
(typedef
d 16비트 부호 없는 정수 = 2바이트 ),struct in_addr sin_addr
(32비트 ipv4 주소 =4 바이트가 필요) 및char sin_zero[8]
(8 바이트).이들 3개의 합계가 14바이트가 됩니다.
이들 3개는 이 14바이트 문자 배열에 저장되어 있으며 적절한 인덱스에 액세스하여 다시 타이핑하여 이들 3개 중 하나에 액세스할 수 있습니다.
user529758의 답변으로 이미 이유를 알 수 있습니다.
아뇨, 그냥 관례가 아니에요
sockaddr
는, 모든 종류의 소켓 동작의 범용 기술자입니다만,sockaddr_in
는, IP 베이스의 통신(IIRC, 「in」은 「InterNet」의 약자)에 고유한 구조입니다.내가 아는 한, 이것은 일종의 "다형성"이다:bind()
함수가 수신한 것처럼 가장하다struct sockaddr *
그러나 실제로는 적절한 타입의 구조가 전달되고 있는 것을 전제로 합니다.즉, 첫 번째 인수로 제공하는 소켓의 타입에 대응하는 것입니다.
이는 바인드가 IP 소켓 이외의 다른 유형의 소켓(예를 들어 sockaddr_un을 유형으로 하는 Unix 도메인 소켓)을 바인딩할 수 있기 때문입니다.AF_의 주소INET 소켓에는 호스트와 포트가 주소로서 설정되어 있습니다만, AF_는 있습니다.UNIX 소켓에는 파일 시스템 경로가 있습니다.
언급URL : https://stackoverflow.com/questions/21099041/why-do-we-cast-sockaddr-in-to-sockaddr-when-calling-bind
'programing' 카테고리의 다른 글
strcpy vs. memcpy (0) | 2022.08.03 |
---|---|
VueJS - 패스 함수명과 콜의 차이 (0) | 2022.08.03 |
클릭 리스너 포함 Renderless Vue 구성 요소 (0) | 2022.08.03 |
"Java Concurrency In Practice"는 아직 유효합니까? (0) | 2022.08.03 |
스택 트레이스란 무엇입니까?어플리케이션오류를 디버깅하려면 어떻게 해야 하나요? (0) | 2022.08.03 |