mojo's Blog
Network Programming: Part I 본문
※ A Client-Server Transaction
대부분의 네트워크 애플리케이션은 클라이언트-서버 모델을 기반으로 한다.
- 서버 프로세스 및 하나 이상의 클라이언트 프로세스들
- 서버가 일부 리소스를 관리한다.
- 서버는 클라이언트의 리소스를 조작하여 서비스를 제공한다.
- 클라이언트의 요구에 의해 서버가 활성화된다 (vending machine analogy)
주목할 점은 클라이언트와 서버 둘 다 host 에서 작동되는 점인데 호스트 둘 다 동일할 수 있거나 다를 수 있다는 점을 알아두도록 하자.
network host 란?
네트워크 호스트(network host)는 컴퓨터 네트워크에 연결된 컴퓨터나 기타 장치이다.
네트워크 호스트는 정보 리소스, 서비스, 애플리케이션을 네트워크 상의 사용자나 기타 노드에 제공할 수 있다.
네트워크 호스트는 네트워크 주소가 할당된 네트워크 노드이다.
※ Hardward Organization of a Network Host
DMA 에 대해 알 필요가 있다.
DMA : Direct Memory Access 의 약자로 특정 하드웨어 하위 시스템이 CPU와 독립적으로 메인 시스템 메모리에 접근할 수 있게 해주는 컴퓨터 시스템의 기능이다.
예를 들어서 다음과 같이 DMA 가 일어날 수 있다.
disk 에서 DRAM 인 main memory 로 DMA 가 일어날 수 있으며 그 반대도 가능하다.
※ Computer Networks
Network 는 지리적 근접성에 따라 구성된 박스와 와이어의 계층 시스템이다.
- SAN(System Area Network)이 클러스터 또는 머신룸에 걸쳐 있다.
- Switched Ethernet, Quadrics QSW, ...
- LAN(Local Area Network)은 건물 또는 캠퍼스에 걸쳐 있다.
- Ethernet 이 가장 두드러진 예시다.
- WAN(Wide Area Network)은 국가 또는 전 세계에 걸쳐 있습니다.
- 일반적으로 고속 point-to-point 전화 회선
Internetwork(internet) 는 상호 연결된 네트워크들의 세트이다.
- 글로벌 IP 인터넷(대문자 "I")은 인터넷(소문자 "i")의 가장 유명한 예시다.
※ Lowest Level : Ethernet Segment
Ethernet segment 는 와이어(twisted pairs)로 허브에 접속된 호스트의 집합으로 구성된다.
Operation
- 각 Ethernet adapter 에는 고유한 48비트 주소(MAC 주소)가 있다.
- 예: 00:16:ea:e3:54:e6
- 호스트는 frame 이라고 하는 chunk 로 다른 호스트에 비트를 송신한다.
- 허브는 각 포트에서 다른 포트로 각 비트를 slavish 한 방식으로 복사 (slavish : 맹종하는)
- 모든 호스트는 모든 bit 를 본다.
- 허브가 없어지고, 브릿지(스위치, 라우터)가 허브를 대체할 수 있을 정도로 저렴해졌다.
※ Lowest Level : Ethernet Segment
브릿지는 어떤 호스트가 어떤 포트에서 도달할 수 있는지를 현명하게 학습한 후 선택적으로 프레임을 포트에서 포트로 복사한다.
※ Conceptual View of LANs
허브, 브리지, 및 와이어는 1개의 와이어에 접속되어 있는 호스트의 집합으로 다음과 같이 표현할 수 있다.
※ Next Level : internets
여러개의 호환성이 없는 LAN 을 라우터라고 불리는 특수한 컴퓨터로 물리적으로 접속할 수 있다.
접속되어 있는 네트워크를 internet 이라고 부른다. (I 아니고 i 임)
LAN 1과 LAN 2는 완전히 다르거나 완전히 호환되지 않을 수 있다.
(ex: Ethernet, Fibre Channel, 802.11*, T1-links, DSL, ...)
※ Logical Structure of an internet
Ad hoc interconnection of networks
- 특정 위상(topology)은 없다.
- 라우터와 링크의 용량이 크게 다르다.
네트워크를 건너 뛰어서 sender 로부터 receiver 로 패킷을 전달한다.
- 라우터가 하나의 네트워크에서 다른 네트워크로 브릿지를 형성한다.
- 패킷마다 루트가 다를 수 있다.
※ The Notion of an internet Protocol
호환성이 없는 LAN과 WAN 간에 비트를 송신하는 것이 어떻게 가능할까?
해결책은 각 호스트와 라우터에서 실행되는 protocol software 이다. (그것이 internet Protocol)
- 호스트와 라우터가 네트워크에서 네트워크로 데이터를 전송할 때 어떻게 협력해야 하는지를 제어하는 규칙 집합이다.
- 서로 다른 네트워크 간의 차이를 완화한다.
그렇다면 internet Protocol 은 무엇을 하나요?
1. Provides a naming scheme
- 인터넷 프로토콜(IP)은 호스트 주소의 통일된 형식을 정의한다.
- 각 호스트(및 라우터)에는 그 호스트를 유일하게 식별하는 적어도 1개의 인터넷 주소가 할당된다.
2. Provides a delivery mechanism
- 인터넷 프로토콜은 표준 전송 장치(패킷)를 정의한다.
- 패킷은 header + payload(data) 로 구성된다.
- header : packet size, source, destination address 등의 정보가 포함된다.
- payload : source host 로 부터 전송된 데이터 비트를 포함한다.
※ Transferring internet Data Via Encapsulation
LAN1 에서 Host A 가 LAN2 에 해당하는 Host B 에게 data 를 전송하는 과정이다.
(1), (2), (3) 순으로 encapsulation 이 일어나면서 data 에 header 를 부착하고 패킷 전송이 일어난다.
(4) 에서 라우터에 도착하게 되면 routing algorithm 을 통해 header 가 (5) 에서 변경되는 것을 볼 수 있다.
(6), (7), (8) 순으로 decapsulation 이 일어나면서 최종적으로 data 를 전송하는 것을 볼 수 있다.
※ Global IP Internet (upper case)
TCP/IP 프로토콜 제품군 기반
- IP (Internet Protocol)
- 호스트 간 패킷(데이터그램)의 기본 이름 지정 체계 및 신뢰할 수 없는 전송 기능 제공
- UDP (Unreliable Datagram Protocol)
- IP를 사용하여 프로세스 간 신뢰할 수 없는 데이터그램 전송 제공
- TCP (Transmission Control Protocol)
- IP를 사용하여 연결을 통해 프로세스 간 안정적인 바이트 스트림 제공
소켓 인터페이스에서 Unix 파일 I/O 및 기능의 혼합을 통해 액세스
※ Hardware and Software Organization of an Internet Application
※ A Programer's View of the Internet
1. 호스트는 32비트 IP 주소 집합에 매핑된다.
- 128.2.203.179
2. IP 주소 집합은 Internet domain names 이라는 식별자 집합에 매핑된다.
- 128.2.203.179 는 www.cs.cmu.edu 에 매핑된다.
3. 한 인터넷 호스트의 프로세스는 연결을 통해 다른 인터넷 호스트의 프로세스와 통신할 수 있다.
※ IP Address
32 비트 IP 주소는 IP address struct 에 저장된다.
- IP 주소는 항상 network byte order(bit-endian byte order)로 메모리에 저장
- 패킷 헤더에서 한 컴퓨터에서 다른 컴퓨터로 전송되는 정수에 대해 일반적으로 참이다.
- 예를 들어, 인터넷 연결을 식별하는 데 사용되는 포트 번호입니다.
struct in_addr {
uint32_t s_addr;
};
※ Dotted Decimal notation
관례적으로, 32비트 IP 주소의 각 바이트는 10진수 값으로 표현되고 마침표로 구분된다.
- IP 주소: 0x8002C2F2 = 128.2.194.242
getaddrinfo 및 getnameinfo 함수를 사용하여 IP 주소와 도트 포함 10진수 형식 간에 변환한다.
※ Internet Domain Names
※ Domain Naming System(DNS)
인터넷은 IP 주소와 도메인 이름 사이의 매핑을 거대한 전세계 분산 데이터베이스에 유지한다.
개념적으로 프로그래머는 DNS 데이터베이스를 수백만 개의 호스트 항목 모음으로 볼 수 있다.
- 각 호스트 항목은 도메인 이름과 IP 주소 집합 간의 매핑을 정의한다.
- 수학적 의미에서 호스트 항목은 도메인 이름과 IP 주소의 동등한 클래스이다.
※ Properties of DNS Mappings
nslookup 을 사용해서 DNS mapping 을 확인할 수 있다.
각 호스트에는 항상 127.0.0.1에 매핑되는 로컬로 정의된 도메인 이름 localhost가 있다.
그리고 hostname 명령어를 사용해서 localhost 의 실제 도메인 이름을 결정할 수 있다.
보통 도메인 이름 단 하나만이 단 하나의 IP address 으로 매핑될 것 같지만 그렇지 않다.
여러개의 도메인 이름이 서로 동일한 IP address 으로 매핑되는 경우가 위와 같이 존재한다.
그리고 도메인 이름 단 하나로 여러개의 IP address 으로 매핑되는 경우가 존재하며 IP address 가 존재하지 않는 경우도 존재한다.
※ Internet Connections
클라이언트와 서버는 연결을 통해 바이트 스트림을 전송하여 통신하며 각 연결은 다음과 같다.
- Point-to-point : 프로세스 쌍을 연결
- Full-duplex : 데이터가 동시에 양방향으로 흐를 수 있음
- Reliable : 원본에서 보낸 바이트 스트림은 대상에서도 보낸 것과 동일한 순서로 수신
소켓은 연결의 endpoint 이다.
- 소켓 주소는 IP 주소이며 포트와 쌍으로 이룸
포트는 프로세스를 식별하는 16비트 정수이다.
- Ephemeral port : 클라이언트가 연결 요청을 할 때 클라이언트 커널에 의해 자동으로 할당됨
- Well-known port : 서버에서 제공하는 일부 서비스와 연결됨(예: 포트 80은 웹 서버와 연결됨)
※ Well-known Ports and Service Names
널리 사용되는 서비스에는 잘 알려진 포트와 그에 상응하는 잘 알려진 서비스 이름이 영구적으로 할당된다.
- echo server : 7/echo
- ssh servers : 22/ssh
- email server : 25/smtp
- Web server : 80/http
잘 알려진 포트와 서비스 이름 간의 매핑은 각 리눅스 시스템의 /etc/services 파일에 포함되어 있다.
※ Anatomy of a Connection
연결은 endpoint 들의 소켓 주소로 고유하게 식별된다 (socket pair)
- (cliaddr:cliport, servaddr: servport)
위 사진으로 보면 클라이언트 측의 IP address 는 128.2.194.242 이고 포트번호는 Ephemeral port 인 51213 이 할당된 것으로 보인다.
그리고 Server 측에서는 포트 번호가 80 인 것으로 보니 HTTP 웹 서버와 연결을 하려고 하는 것으로 보이고 IP address 는 208.216.181.15 인 것으로 볼 수 있다.
※ Sockets
Socket 이란?
- 커널에서 소켓은 통신의 end-point 이다.
- application 에서 소켓은 응용 프로그램이 네트워크에서 읽거나 쓸 수 있도록 하는 file descriptor 이다.
- 네트워크를 포함한 모든 Unix I/O 장치가 파일로 모델링된 것을 기억하자
클라이언트와 서버는 socket descriptor 를 읽고 쓰면서 서로 통신한다.
일반 파일 I/O와 소켓 I/O의 주요 차이점은 application 이 socket descriptor 를 "open" 하는 방법이다.
※ Socket Address Structures
Generic socket address :
- connect, binding 및 accept 에 대한 address arguments
- 소켓 인터페이스를 설계할 때 C에 일반(void *) 포인터가 없었기 때문에 필요하다.
- casting 편의성을 위해 Stevens 규약을 채택한다. (typedef struct sockaddr SA;)
Internet-specific socket address :
socket address argument 들을 사용하는 함수에 대해서 (struct sockaddr_in *)를 (struct sockaddr *)로 캐스팅해야 한다.
※ Socket Interface
client 측, server 측의 clientfd, listenfd 으로 소켓 디스크립터를 가지고 통신하는 매커니즘을 이해하자.
client 가 connect 를 요청하면 server 측에서 accept 하여 data exchange 가 일어난다.
※ Host and Service Conversion : getaddrinfo
getaddrinfo는 호스트 이름, 호스트 주소, 포트 및 서비스 이름의 문자열 표현을 소켓 주소의 struct 으로 변환하는 현대적인 방법이다.
- 사용되지 않는 gethost를 이름으로 대체하고 getservbyname 함수를 지정한다.
장점:
- Reentrant (스레드 프로그램에서 안전하게 사용할 수 있다)
- 휴대용 프로토콜 독립 코드를 작성할 수 있다.
- IPv4와 IPv6 모두에서 작동
단점
- 다소 복잡하다.
- 다행히도, 극소의 사용 패턴은 대부분의 경우 충분하다.
int getaddrinfo(const char *host, /* Hostname or address */
const char *service, /* Port or service name */
const struct addrinfo *hints, /* Input parameters */
struct addrinfo **result); /* Output linked list */
void freeaddrinfo(struct addrinfo *result); /* Free linked list */
const char *gai_strerror(int errcode); /* Return error msg */
host 와 서비스가 주어지면 getaddrinfo는 addrinfo struct 의 링크된 목록을 가리키는 결과를 반환하며, 각 구조는 해당 소켓 주소 구조를 가리키며 소켓 인터페이스 함수에 대한 인자를 포함한다.
Helper functions :
- freeaddrinfo () 함수는 링크드 리스트를 free 해주는 역할을 한다.
- gai_sterrror는 오류 코드를 오류 메시지로 변환한다.
※ Linked List Returned by getaddrinfo
클라이언트: 소켓 및 연결에 대한 호출이 성공할 때까지 이 목록을 따라 각 소켓 주소를 차례로 시도한다.
서버: 소켓 및 바인딩 호출이 성공할 때까지 목록을 수행한다.
※ addrinfo Struct
getaddrinfo 에서 반환되는 각 addrinfo 구조체에는 소켓 함수로 직접 전달할 수 있는 인자가 포함되어 있다.
또한 연결 및 바인딩 기능에 직접 전달할 수 있는 소켓 주소 구조를 가리킨다.
※ Host and Service Conversion : getnameinfo
getnameinfo는 소켓 주소를 해당 호스트와 서비스로 변환하는 getaddrinfo 의 역 관계이다.
- 사용되지 않는 gethostbyaddr 및 getservbyport 함수를 대체한다.
- Reentrant 및 protocol 에 독립적이다.
※ Conversion Example
/* $begin hostinfo */
#include "csapp.h"
int main(int argc, char **argv)
{
struct addrinfo *p, *listp, hints;
char buf[MAXLINE];
int rc, flags;
if (argc != 2) {
fprintf(stderr, "usage: %s <domain name>\n", argv[0]);
exit(0);
}
/* Get a list of addrinfo records */
memset(&hints, 0, sizeof(struct addrinfo));
#if 0
hints.ai_family = AF_INET; /* IPv4 only */ //line:netp:hostinfo:family
#endif
hints.ai_socktype = SOCK_STREAM; /* Connections only */ //line:netp:hostinfo:socktype
if ((rc = getaddrinfo(argv[1], NULL, &hints, &listp)) != 0) {
fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(rc));
exit(1);
}
/* Walk the list and display each IP address */
flags = NI_NUMERICHOST; /* Display address string instead of domain name */
for (p = listp; p; p = p->ai_next) {
Getnameinfo(p->ai_addr, p->ai_addrlen, buf, MAXLINE, NULL, 0, flags);
printf("%s\n", buf);
}
/* Clean up */
Freeaddrinfo(listp);
exit(0);
}
/* $end hostinfo */
'학교에서 들은거 정리 > 시스템프로그래밍' 카테고리의 다른 글
Concurrent Programming (0) | 2022.04.14 |
---|---|
Network Programming: Part II (0) | 2022.04.08 |
System-Level I/O (0) | 2022.04.01 |
Exceptional Control Flow: Signals and Nonlocal Jumps (0) | 2022.03.25 |
Exceptional Control Flow: Exceptions and Process (0) | 2022.03.17 |