programing

Sockaddr 구조에서 IPV4 주소 가져오기

goodsources 2022. 8. 18. 23:49
반응형

Sockaddr 구조에서 IPV4 주소 가져오기

IP 주소를 문자열로 추출하려면 어떻게 해야 합니까?그 방법을 알려주는 참고 자료를 찾을 수 없습니다.char sa_data[14]부호화 되어 있습니다.

그냥 다 캐스팅해.sockaddr구조를 sockaddr_in으로 만듭니다.다음으로 다음을 사용할 수 있습니다.

char *ip = inet_ntoa(their_addr.sin_addr)

표준 IP 표현을 취득합니다.

inet_ntoa()IPv4 에 대응합니다.inet_ntop()는, IPv4 와 IPv6 의 양쪽 모두에서 동작합니다.

입력이 주어지다struct sockaddr *res다음은 두 가지 코드 조각입니다(macOS에서 테스트됨).

inet_ntoa() 사용

#include <arpa/inet.h>

struct sockaddr_in *addr_in = (struct sockaddr_in *)res;
char *s = inet_ntoa(addr_in->sin_addr);
printf("IP address: %s\n", s);

inet_ntop() 사용

#include <arpa/inet.h>
#include <stdlib.h>

// obviously INET6_ADDRSTRLEN is expected to be larger
// than INET_ADDRSTRLEN, but this may be required in case
// if for some unexpected reason IPv6 is not supported, and
// INET6_ADDRSTRLEN is defined as 0
// but this is not very likely and I am aware of no cases of
// this in practice (editor)
char s[INET6_ADDRSTRLEN > INET_ADDRSTRLEN ? INET6_ADDRSTRLEN : INET_ADDRSTRLEN]
    = '\0';

switch(res->sa_family) {
    case AF_INET: {
        struct sockaddr_in *addr_in = (struct sockaddr_in *)res;

        ////char s[INET_ADDRSTRLEN] = '\0';
            // this is large enough to include terminating null

        inet_ntop(AF_INET, &(addr_in->sin_addr), s, INET_ADDRSTRLEN);
        break;
    }
    case AF_INET6: {
        struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)res;
        
        ////char s[INET6_ADDRSTRLEN] = '\0';
            // not sure if large enough to include terminating null?

        inet_ntop(AF_INET6, &(addr_in6->sin6_addr), s, INET6_ADDRSTRLEN);
        break;
    }
    default:
        break;
}
printf("IP address: %s\n", s);

에밀의 답변은 맞지만 제가 알기로는inet_ntoa권장되지 않습니다.그 대신에inet_ntopIPv4 를 사용하고 있는 경우는,struct sockaddr로.sockaddr_in코드는 다음과 같습니다.

struct addrinfo *res;   // populated elsewhere in your code
struct sockaddr_in *ipv4 = (struct sockaddr_in *)res->ai_addr;
char ipAddress[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &(ipv4->sin_addr), ipAddress, INET_ADDRSTRLEN);

printf("The IP address is: %s\n", ipAddress);

IPv6 주소에 대해서 이것을 실시하는 방법 등, 상세한 에 대하여는, 이 뛰어난 자원을 봐 주세요.

한번만sockaddr에 던지다.sockaddr_in, 다음과 같이 됩니다.

struct sockaddr_in {
    u_short     sin_family;
    u_short     sin_port;
    struct      in_addr sin_addr;
    char        sin_zero[8];
};

다음 프로그램은 지정된 도메인을 해결합니다.

$ gcc a.c

$ ./a.out google.com
AF_INET: 216.58.214.238
AF_INET6: 2a00:1450:400d:803::200e

$ ./a.out google.com af_inet
AF_INET: 216.58.214.238

a.c:

#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>

int
main(int argc, char *argv[])
{
    struct addrinfo hints, *res, *cres;
    int r;
    char s[INET6_ADDRSTRLEN];

    memset(&hints, 0, sizeof(hints));
    if (argc > 2)
        hints.ai_family = AF_INET;
    hints.ai_socktype = SOCK_DGRAM;

    r = getaddrinfo(argv[1], NULL, &hints, &res);
    if (r) {
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(r));
        exit(EXIT_FAILURE);
    }

    for (cres = res; cres; cres = cres->ai_next) {
        switch (cres->ai_family) {
        case AF_INET:
            inet_ntop(AF_INET, &((struct sockaddr_in *)cres->ai_addr)->sin_addr, s, INET6_ADDRSTRLEN);
            printf("AF_INET: %s\n", s);
            break;
        case AF_INET6:
            inet_ntop(AF_INET6, &((struct sockaddr_in6 *)cres->ai_addr)->sin6_addr, s, INET6_ADDRSTRLEN);
            printf("AF_INET6: %s\n", s);
            break;
        }
    }

    freeaddrinfo(res);
}

또 다른 예는 여기에서 찾을 수 있습니다.

사용할 수 있습니다.getnameinfo WindowsLinux 용입니다.

당신이 좋은 물건을 가지고 있다고 가정한다(즉, 그 물건의 구성원은 적절한 가치를 가지고 있다)sockaddr*불렀다pSockaddr:

char clienthost[NI_MAXHOST];  //The clienthost will hold the IP address.
char clientservice[NI_MAXSERV];
int theErrorCode = getnameinfo(pSockaddr, sizeof(*pSockaddr), clienthost, sizeof(clienthost), clientservice, sizeof(clientservice), NI_NUMERICHOST|NI_NUMERICSERV);

if( theErrorCode != 0 )
{
    //There was an error.
    cout << gai_strerror(e1) << endl;
}else{
    //Print the info.
    cout << "The ip address is = " << clienthost << endl;
    cout << "The clientservice = " << clientservice << endl;
}

활자 주조sockaddr로.sockaddr_in및 ipv4의 취득에 대해서inet_ntoa

char * ip = inet_ntoa(((struct sockaddr_in *)sockaddr)->sin_addr);

언급URL : https://stackoverflow.com/questions/1276294/getting-ipv4-address-from-a-sockaddr-structure

반응형