programing

bind()를 호출할 때 sockaddr_in을 sockaddr에 캐스팅하는 이유는 무엇입니까?

prostudy 2022. 8. 3. 20:54
반응형

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(typedefd 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

반응형