2012-10-10 2 views
7

현재 클라이언트로부터 요청을받는 UDP 서버에서 작업 중입니다. 내가받는 데이터 그램은 마지막 5 개의 요소가 포트 번호 인 바이트 (char) 배열 5 개 요소입니다.sockaddr_storage에서 IP 주소 및 포트 정보 추출

결국이 서버는 자신의 데이터 그램에서 IP 주소와 포트 번호를 모두 반환해야합니다.

저는 inet_ntop과 sockaddr 구조체를 연결하고 IP를 출력하기 위해받은 구조체를 사용하는 방법을 이미 알고 있지만, 원하는 형식으로되어 있지 않은 문자열을 반환합니다.

string1 = inet_ntop(their_addr.ss_family,get_in_addr(
    (struct sockaddr *)&their_addr),s, sizeof s); 

반환 :

127.0.0.1 

나 :

[127][0][0][1] 

내가 캐릭터의 어떤 종류를 사용해야합니다

[1][2][7][.][0][.][0][.][1] 

내가 좋아하는 뭔가가 필요 예를 들어 내 4 요소 바이트를 만들기위한 배열 조작 배열? 아니면 sockaddr가이 16 진수 형식으로 남겨두고 반환 할 수있는 방식으로이 정보를 가지고 있습니까?

답변

12

IPv4로 가정합니다.

sockaddr_storage 또는 sockaddr 구조의 주소를 가져 와서 IPv4 버전 sockaddr_in으로 캐스팅 한 후 IPv4 주소의 개별 바이트에 액세스 할 수 있습니다.

struct sockaddr_in *sin = (struct sockaddr_in *)&their_addr; 

그렇다면 (네트워크 바이트 순서) IP 어드레스의 4 바이트를 보유하는 32 비트 값 (in_addr_t) 인 s_addr 부재의 주소를 가져 가서 unsigned char 포인터로 전송할 수있는 그런 다음 값의 개별 바이트에 액세스 할 수 있습니다. 이것은 내가 찾던 정확히 무엇

int getnameinfo(const struct sockaddr *sa, socklen_t salen, 
        char *host, size_t hostlen, 
        char *serv, size_t servlen, int flags); 

예컨대 :

struct sockaddr_storage client_addr; 
socklen_t client_len = sizeof(struct sockaddr_storage); 

/* Accept client request */ 
int client_socket = accept(server_socket, 
    (struct sockaddr *)&client_addr, &client_len); 

char hoststr[NI_MAXHOST]; 
char portstr[NI_MAXSERV]; 

int rc = getnameinfo((struct sockaddr *)&client_addr, 
    client_len, hoststr, sizeof(hoststr), portstr, sizeof(portstr), 
    NI_NUMERICHOST | NI_NUMERICSERV); 

if (rc == 0) 
    printf("New connection from %s %s", hoststr, portstr); 
+0

:

unsigned char *ip = (unsigned char *)&sin->sin_addr.s_addr; printf("%d %d %d %d\n", ip[0], ip[1], ip[2], ip[3]); 
Ryanman

5

당신은 아마 getnameinfo() 기능을 사용하십시오. 간결하고 우수한. 감사합니다 @ Kludas