Programming Languages/C

[WSA] Visual Studio에서 inet_ntoa( ) 대체하기

ubiquitous4g 2021. 9. 8. 19:01

문제점

Visual Studio에서 권장하지 않는 함수들( 'scanf', fopen', 'strcpy') 사용시 Warning C4996 경고가 발생한다.

소켓 프로그래밍의 경우, inet_ntoa( ) 함수 사용시 IPv4만 지원해 해당 경고가 발생한다.

inet_ntoa 뜻: network-to-address, 비트 단위 IP 주소를 문자열 주소값으로 변환한다.
n = network : 비트 단위 IP 주소값 + 빅 엔디언 (네트워크는 비트 단위로 통신한다.)
a = address : 문자열 단위 IP 주소값 + 리틀 엔디언

해결책

1. Visual Studio 경고를 무시

#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:4996)

2. inet_ntoa( ) -> inet_ntop( ) 함수를 사용한다.

//inet_ntoa 사용 문장
//printf("[client IP:%s,PORT:%d] accepted\n", inet_ntoa(clientAddress.sin_addr), ntohs(clientAddress.sin_port));

#include <ws2tcpip.h>

char clientIP[20] = { 0 };//dst : 결과 저장
if (inet_ntop(AF_INET, &clientAddress.sin_addr, clientIP, sizeof(clientIP)) == NULL)
	ErrorMsg("inet_ntop");
else
	printf("[client IP:%s,PORT:%d] accepted\n", clientIP, ntohs(clientAddress.sin_port));

+추가 inet_addr -> inet_pton( )

//inet_addr 사용 문장
//Address.sin_addr.s_addr = inet_addr(SERVER_IP);   //inet_ntoa

#include <ws2tcpip.h>

result = inet_pton(AF_INET, SERVER_IP, &(serverAddress.sin_addr));
if (result == -1) 
	ErrorMsg("inet_pton");
else 
	OKMsg("inet_pton");

3. WSAStringToAddress()/WSAAddressToString() 함수 사용

#include <winsock2.h>

INT WSAStringToAddress(
    LPTSTR AddressString, // 문자열 IP와 PORT번호 
    INT AddressFamily,    // 주소체계
    LPWSAPROTOCOL_INFO lpProtocolInfo, // Protocol Provider, 일반적으로 NULL
    LPSOCKADDR lpAddress, // 바이트 형식 IP와 PORT번호 담을 구조체
    LPINT lpAddressLength // 네번째 인자 크기
);
// -> 성공시 0, 실패시 SOCKET_ERROR 반환

INT WSAAddressToString(
    LPSOCKADDR lpsaAddress, // 바이트 형식 IP와 PORT번호 
    DWORD dwAddressLength,  // 첫번째 인자 크기
    LPWSAPROTOCOL_INFO lpProtocolInfo,// Protocol Provider, 일반적으로 NULL
    LPTSTR lpszAddressString, // 문자열 형식 IP와 PORT번호 담을 구조체
    LPDWORD lpdwAddressStringLength // 네번째 인자 크기 
);
// -> 성공시 0, 실패시 SOCKET_ERROR 반환

구현 예제

#undef UNICODE
#undef _UNICODE
#include <stdio.h>
#include <winsock2.h>

int main(int argc, char *argv[])
{
	char *strAddr="203.211.218.102:9190";
    
    char strAddrBuf[50];
    SOCKADDR_IN servAddr;
    int size;
    
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2,2), &wsaData);
    
    size=sizeof(serv_adr);
    WSAStringToAddress(strAddr, AF_INET, NULL, (SOCKADDR*)&servAddr, &size);
    
    size=sizeof(strAddrBuf);
    WSAAddressToString((SOCKADDR*)&servAddr, sizeof(servAddr), NULL, strAddrBuf, &size);
    
    printf("Second conv result: %s \n", strAddrBuf);
    WSACleanup();
    return 0;
}