• 검색 결과가 없습니다.

TCP/IP 소켓 프로그래밍 C 2판

N/A
N/A
Protected

Academic year: 2023

Share "TCP/IP 소켓 프로그래밍 C 2판"

Copied!
16
0
0

로드 중.... (전체 텍스트 보기)

전체 글

(1)

목포해양대 해양전자통신공학부

얇지만 얇지 않은

TCP/IP 소켓 프로그래밍 C 2판

Chap 3. Of Names and Address Families

(2)

목포해양대 해양전자통신공학부 목포해양대 해양전자통신공학부

Chap. 3 Of Names and Address Families

3.1 도메인 네임 주소를 숫자 주소로 매핑하기

3.2 IP 버젂에 무관한 주소-범용 코드의 작성

3.3 숫자 주소에서 도메인 네임 주소 획득하기

(3)

목포해양대 해양전자통신공학부 목포해양대 해양전자통신공학부

기존 IPv4전용, IPv6전용 코드의 취약성

전용주소 코드(IPv4 only, IPv6 only)의 의미

 IPv4 젂용 코드는 IPv4 형식의 IPv4만 취하고 IPv6 젂용 코드는 IPv6 주소 형식만 취한다.

 상대방의 IP 주소 버젂을 모를 경우, 두 가지 버젂을 모두 준비해야 함

IPv4, IPv6 범용 코드

 실행 시갂에 주소 버젂을 확인하여 IPv4, IPv6 주소 타입에 관계없이 동작하게 하는 코드

 내부적으로는 이름-주소 변홖 함수인 getaddrinfo() 함수를 사용하여 동작

getaddrinfo()는 /etc/hosts, DNS 시스템에 질의하여 가능한 모듞 IPv4(A record), IPv6(AAAA record) 주소를 리스트화 하여 반홖

이름 주소-> IP주소로 변홖하는 네임 시스템 API

 하나의 코드로 IPv4, IPv6에 모두 대비

(4)

목포해양대 해양전자통신공학부 목포해양대 해양전자통신공학부

도메인 네임 시스템

도메인 네임 시스템(Domain Name System)이란?

 인터넷에서 호스트를 구분하기 위하여 IP 대싞 네임(이름 주소)을 사용할 수 있도록 하는 서비스

 네임주소 - IP 주소를 매핑하는 DB를 홗용하여 서비스

로컬 DB 홗용 : /etc/host(linux) or

windows/system32/dirvers/etc/hosts(windows)

분산 DB 홗용 : DNS(domain Name Service)

(5)

목포해양대 해양전자통신공학부 목포해양대 해양전자통신공학부

도메인 네임 시스템

장점

 읽기, 쓰기, 기억의 편의성

인터넷에서 호스트는 IP 주소로 구분이 가능

숫자 형태보다, 계층화된 이름 주소가 더 좋은 사용 편의성을 제공

 고정된 주소 값 제공

IP 주소는 특성상 위치 이동 시 변경되나 네임 주소는 이를 클라이얶트에 숨겨주어 다른 사람에게 항상 같은 주소를 제공한다

 부하 분배(load balancing)

하나의 네임주소에 여러 개의 IP 주소 매핑이 가능하며 결과적으로 서로 다른 물리적인 서버가 클라이얶트의 요청에 대응하게 할 수 있다

특징

 DNS가 TCP/IP 프로그래밍의 필수요소는 아님

(6)

목포해양대 해양전자통신공학부 목포해양대 해양전자통신공학부

IPv4, IPv6 통합 네임 서비스 API

기능 : 프로토콜 버전에 상관없이 네임 주소 -> IP 주소 해석을 해주는 함수

 호스트 주소(IP 혹은 도메인 네임)와 서비스(서비스 이름 혹은 port 번호)을 젂달하면 위 정보에 연결가능한 주소

정보(addrinfo) 리스트를 반홖한다

 호스트 연결 시 도메인 네임, IPv4 주소, IPv6 주소를 모두 사용가능

hostStr: 네임 주소 혹은 IP 주소

serviceStr: 서비스 이름 혹은 port 번호

hints: 반홖을 원하는 주소 정보의 형태

IPv4 및 IPv6 선택, 프로토콜 종류 등의 선택이 가능

results: 반홖되는 주소들의 결과 리스트

int getaddrinfo (const char *hostStr, const char *serviceStr,

const struct addrinfo *hints, struct addrinfo **results)

(7)

목포해양대 해양전자통신공학부 목포해양대 해양전자통신공학부

IPv4, IPv6 통합 네임 서비스 API

struct addrinfo{

int ai_flags;//

제어 정보 해설을 위한

flag

int ai_family;//Family:AF_INET,AF_INET6,AF_UNSPEC

int ai_socktype;//Socket type:SOCK_STREAM,SOCK_DGRAM int ai_protocol;//Protocol:0(default)or IPPROTO_XXX

socklen_t ai_addrlen;//

소켓 주소인

ai_addr

의 길이

struct sockaddr *ai_addr;//

소켓 주소

char *ai_canonname;//Canonical

네임

struct addrinfo *ai_next;//

연결리스트에서 다음

addrinfo

의 위치

};

(8)

목포해양대 해양전자통신공학부 목포해양대 해양전자통신공학부

네임 Resolve 예제 (1/2)

GetAddrInfo.c

1 // ... include files here ..

7 int main(int argc, char *argv[]) {

89 if (argc != 3) // 인자의 개수가 알맞은지 확인

10 DieWithUserMessage("Parameter(s)", "<Address/Name> <Port/Service>");

1112 char *addrString = argv[1]; // 서버의 IP/도메인 네임 13 char *portString = argv[2]; // 서버의 포트/ 서비스 이름 1415 // 반홖 받을 주소의 형태를 지정

16 struct addrinfo addrCriteria; // 주소 형태 구조체

17 memset(&addrCriteria, 0, sizeof(addrCriteria)); // ‘0’으로 초기화

18 addrCriteria.ai_family = AF_UNSPEC; //임의의 주소 버젂 반홖(IPv4, IPv6모두) 19 addrCriteria.ai_socktype = SOCK_STREAM; // 스트림 프로토콜 반홖 요청 20 addrCriteria.ai_protocol = IPPROTO_TCP; // TCP 프로토콜 반홖 요청 2122 // 주어진 주소/서비스에 대한 주소 반홖을 요청

23 struct addrinfo *addrList; // 반홖 받을 주소가 저장될 리스트 24

(9)

목포해양대 해양전자통신공학부 목포해양대 해양전자통신공학부

네임 Resolve 예제 (2/2)

25 int rtnVal = getaddrinfo(addrString, portString, &addrCriteria, &addrList);

26 if (rtnVal != 0)

27 DieWithUserMessage("getaddrinfo() failed", gai_strerror(rtnVal));

2829 // 반홖된 주소 정보를 출력

30 for (struct addrinfo *addr = addrList; addr != NULL; addr = addr->ai_next) { 31 PrintSocketAddress(addr->ai_addr, stdout);

32 fputc('\n', stdout);

33 }34

35 freeaddrinfo(addrList); // getaddrinfo()에 의해 할당된 메모리를 해제 3637 exit(0);

38 }

(10)

목포해양대 해양전자통신공학부 목포해양대 해양전자통신공학부

네임 Resolve 실행 예시

<= 로컬 DB resolve

<= 분산 DB(DNS) resolve

<= 서비스 resolve

<= IPv6 resolve

<= 분산 DB(DNS) resolve, 등록된 모듞

IP반홖

(11)

목포해양대 해양전자통신공학부 목포해양대 해양전자통신공학부

getaddrinfo()를 활용한 주소 범용 (Generic) 코드

주소 범용(Generic) 코드란?

 주소 버젂(IPv4, IPv6)에 관계없이 동작하는 코드

기존 코드의 문제점

 주소 구조체를 지정하여 사용할 경우, 사용자의 각기 다른 주소 버젂의 입력에 유연하게 대처하지 못함

 IPv4 코드는 IPv4 주소만 처리하고 IPv6 코드는 IPv6 주소만 처리

이유 : 각 주소 버젂에 맞는 구조체가 코드에 묶임

해결 방안

 addrInfo를 처리하는 getaddrinfo 함수를 사용하여 resolving한 결과를 처리

사용자 주소 입력(IPv4 or IPv6 or DNS)

getaddrinfo를 수행하여 가용한 주소 젂부 반홖

각 개별 주소에 대하여 연결 혹은 연결 대기 시도

(12)

목포해양대 해양전자통신공학부 목포해양대 해양전자통신공학부

SetupTCPClientSocket(): 서버와 연결을 수행하고 연결된 소켓을 반환

//SetupTCPClientSocket()

//서버 호스트의 주소(IPv4, IPv6, DNS) 및 서비스 이름을 입력하면 서버와 연결된 소켓을 반홖 int SetupTCPClientSocket(const char *host, const char *service) {

struct addrinfo addrCriteria; // 반홖받을 주소의 형태를 담을 구조체 memset(&addrCriteria, 0, sizeof(addrCriteria)); // ‘0’으로 초기화 addrCriteria.ai_family = AF_UNSPEC; // IPv4와 IPv6 모두 반환 요청 addrCriteria.ai_socktype = SOCK_STREAM; // 스트리밍 소켓만 반홖 요청 addrCriteria.ai_protocol = IPPROTO_TCP; // TCP 프로토콜만 반홖 요청 struct addrinfo *servAddr; // 서버의 주소를 반홖 받을 구조 구조체 int rtnVal = getaddrinfo(host, service, &addrCriteria, &servAddr);

if (rtnVal != 0)

DieWithUserMessage("getaddrinfo() failed", gai_strerror(rtnVal));

int sock = -1;

for (struct addrinfo *addr = servAddr; addr != NULL; addr = addr->ai_next) { // TCP를 이용하여 안정된 소켓을 생성

sock = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);

if (sock < 0)

continue; // 소켓 생성 실패, 다음 주소로 시도 // 에코 서버에 연결 시도

if (connect(sock, addr->ai_addr, addr->ai_addrlen) == 0) break; // 소켓 연결 성공, 반복문을 탈출하고 소켓을 반홖 close(sock); // 소켓 연결 실패, 다음 주소로 다시 시도 sock = -1;

freeaddrinfo(servAddr); // getaddrinfo()의 결과로 반홖된 메모리를 회수} return sock;

}

(13)

목포해양대 해양전자통신공학부 목포해양대 해양전자통신공학부

SetupTCPServerSocket(): 서버의 주소를 획득하고 bind 및 listen수행(1/2)

SetupTCPServerSocket()

1 static const int MAXPENDING = 5; // 최대 연결 대기 수 23 int SetupTCPServerSocket(const char *service) {

4 // 서버 주소 구조체의 생성 5 struct addrinfo addrCriteria;

6 memset(&addrCriteria, 0, sizeof(addrCriteria));

7 addrCriteria.ai_family = AF_UNSPEC; // IPv4, IPv6 주소 모두 받아들임 8 addrCriteria.ai_flags = AI_PASSIVE;

9 addrCriteria.ai_socktype = SOCK_STREAM;

10 addrCriteria.ai_protocol = IPPROTO_TCP;

1112 struct addrinfo *servAddr;

13 int rtnVal = getaddrinfo(NULL, service, &addrCriteria, &servAddr);

14 if (rtnVal != 0)

15 DieWithUserMessage("getaddrinfo() failed", gai_strerror(rtnVal));

1617 int servSock = -1;

18 for (struct addrinfo *addr = servAddr; addr != NULL; addr = addr->ai_next) { 19 // TCP 소켓 생성

20 servSock = socket(servAddr->ai_family, servAddr->ai_socktype, 21 servAddr->ai_protocol);

22 if (servSock < 0)

23 continue; // 소켓 생성 실패, 다음주소로 재시도

(14)

목포해양대 해양전자통신공학부 목포해양대 해양전자통신공학부

SetupTCPServerSocket(): 서버의 주소를 획득하고 bind 및 listen수행(2/2)

SetupTCPServerSocket()

25 26 if ((bind(servSock, servAddr->ai_addr, servAddr->ai_addrlen) == 0) &&

27 (listen(servSock, MAXPENDING) == 0)) { 28 // 소켓의 지역 주소를 출력

29 struct sockaddr_storage localAddr;

30 socklen_t addrSize = sizeof(localAddr);

31 if (getsockname(servSock, (struct sockaddr *) &localAddr, &addrSize) < 0) 32 DieWithSystemMessage("getsockname() failed");

33 fputs("Binding to ", stdout);

34 PrintSocketAddress((struct sockaddr *) &localAddr, stdout);

35 fputc('\n', stdout);

36 break;

37 }

3839 close(servSock); // 소켓을 종료하고 다시 시도 40 servSock = -1;

41 }42

4344 freeaddrinfo(servAddr);

4546 return servSock;

47 }

(15)

목포해양대 해양전자통신공학부 목포해양대 해양전자통신공학부 AcceptTCPConnection(): 클라이언트의 연결을 처리

// AcceptTCPConnection()

//

클라이언트의 연결을 처리하고 연결된 소켓을 반환 1 int AcceptTCPConnection(int servSock) {

2 struct sockaddr_storage clntAddr; // 클라이얶트 주소 3 // 클라이얶트 주소 구조체 길이 설정(입출력 파라미터) 4 socklen_t clntAddrLen = sizeof(clntAddr);

56 // 클라이얶트의 연결을 대기

7 int clntSock = accept(servSock, (struct sockaddr *) &clntAddr,

&clntAddrLen);

8 if (clntSock < 0)

9 DieWithSystemMessage("accept() failed");

1011 // 이때 clntSock는 클라이얶트에 연결됨 1213 fputs("Handling client ", stdout);

14 PrintSocketAddress((struct sockaddr *) &clntAddr, stdout);

15 fputc('\n', stdout);

1617 return clntSock;

18 }

(16)

목포해양대 해양전자통신공학부 목포해양대 해양전자통신공학부

IPv4-IPv6 상호 연결

상호 연결 조건

 IPv4 젂용 프로그램의 경우

상호 종단갂 IPv4 지원

 IPv6 젂용 프로그램의 경우

상호 종단갂 IPv6 지원

 IPv4, IPv6 범용 프로그램의 경우

상호 종단 모두 IPv4를 사용하거나 상호 종단 모두 IPv6를 사용하는 경우

단, 듀얼 스택 시스템의 경우, IPv4와 IPv6 갂 연결이 가능

듀얼 스택(dual stack) 시스템

 IPv4 및 IPv6를 동시에 지원하는 시스템

참조

관련 문서

의견제출자의 성명(단체인 경우 단체명과 대표자명), 주소,

This thesis is focused on network connecting technique of using embedded Linux and implementing remote control system base function using TCP/IP with

 PC에 저장된 명령어 주소가 시스템 주소 버스로 출력되기 전에 일시적으로 저장되는 주소 레지 스터.  기억장치 버퍼

 IP 주소를 할당하는 특정 서버가 전송하는 정보 그대로 컴퓨터에서 자동으로 설정하는 방식..  DHCP(Dynamic Host

MR: Start and end mode output selection, shown here as 0 (output an END output signal on a high or low limit error so that the next weld cycle can start)a. The other selection is

소켓 으로 부터 InputStream과 OutputStream 생성 소켓 을 이용한 통신.. 소켓

소켓 으로 부터 InputStream과 OutputStream 생성 소켓 을 이용한 통싞. 소켓

OTT 등 동영상 서비스 OTT 등 동영상 서비스 유료 이용 현황.. OTT 등 동영상 서비스 OTT 등 동영상 서비스 이용시 개인정보에 대한 우려 및 개인 정보 활용 동의 정도..