ํฌ์ŠคํŠธ

CS โ€” ipc followup

CS โ€” ipc followup

๐Ÿ“• 05/13 โ€” IPC ๋ชจ์˜๋ฉด์ ‘ ๊ผฌ๋ฆฌ์งˆ๋ฌธ ์ •๋ฆฌ

22_ipc.md ๋ชจ์˜๋ฉด์ ‘ ์งํ›„ ๋‚˜์˜จ ํ›„์† ์งˆ๋ฌธ 1๊ฐœ๋ฅผ ๊นŠ์ด ์žˆ๊ฒŒ ์ •๋ฆฌํ•œ ๋…ธํŠธ. ๋ณธ๋ฌธ์€ 22๋ฒˆ ์›๋ณธ์˜ ํ•ด๋‹น ์„น์…˜์„ ๊ฐ€๋ฆฌํ‚ค๊ณ , ์—ฌ๊ธฐ์„œ๋Š” ๊ฒฐ๋ก  โ†’ ํ๋ฆ„ โ†’ ํ‘œ โ†’ ์ฝ”๋“œ/์˜ˆ โ†’ ๋ฉด์ ‘ ๋‹ต๋ณ€ ํ•œ ์ค„ ์ˆœ์œผ๋กœ ์••์ถ•ํ•œ๋‹ค.


๋ชฉ์ฐจ

  1. ์†Œ์ผ“์ด๋ž€ ๋ฌด์—‡์ผ๊นŒ

1. ์†Œ์ผ“์ด๋ž€ ๋ฌด์—‡์ผ๊นŒ

ํ•œ ์ค„ ๊ฒฐ๋ก  โ€” ์†Œ์ผ“(socket)์€ ๋„คํŠธ์›Œํฌ ๋˜๋Š” ๊ฐ™์€ ๋จธ์‹  ์•ˆ์—์„œ ๋‘ endpoint๋ฅผ ์ž‡๋Š” ์–‘๋ฐฉํ–ฅ ํ†ต์‹  ์ฑ„๋„์˜ ์ถ”์ƒํ™”์ด๊ณ , OS๊ฐ€ ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ(file descriptor) ๋กœ ๋…ธ์ถœํ•˜๋Š” IPC/๋„คํŠธ์›Œํฌ ํ†ตํ•ฉ ์ธํ„ฐํŽ˜์ด์Šค๋‹ค. 22๋ฒˆ IPC ยง10์˜ ์นดํƒˆ๋กœ๊ทธ๋ฅผ ํ•œ ํ•ญ๋ชฉ์”ฉ ๋” ํ’€์–ด๋ณด๋ฉด, ์†Œ์ผ“์€ ๊ฐ™์€ ๋จธ์‹  IPC(UNIX domainยทloopback)๋ถ€ํ„ฐ ๊ธ€๋กœ๋ฒŒ ๋„คํŠธ์›Œํฌ ํ†ต์‹ (TCP/UDP)๊นŒ์ง€ ๊ฐ™์€ API(BSD socket)๋กœ ๋‹ค๋ฃจ๋Š” ๊ฐ€์žฅ ๋ฒ”์šฉ์ ์ธ ๋ฉ”์ปค๋‹ˆ์ฆ˜์ด๋‹ค.

1-1. ์ •์˜ โ€” endpoint + fd ์ถ”์ƒํ™”

1
2
3
4
ํ”„๋กœ์„ธ์Šค A โ†โ”€โ”€[์–‘๋ฐฉํ–ฅ ์ฑ„๋„]โ”€โ”€โ†’ ํ”„๋กœ์„ธ์Šค B
   โ†‘                                โ†‘
 ์†Œ์ผ“ 1                           ์†Œ์ผ“ 2
 (fd: 4)                          (fd: 5)

์†Œ์ผ“์˜ ๋‘ ๊ฐ€์ง€ ๋ณธ์งˆ:

์ธก๋ฉด์˜๋ฏธ
endpoint (์ข…์ )ํ†ต์‹ ์˜ ํ•œ์ชฝ ๋. ๊ฐ ํ†ต์‹ ๋งˆ๋‹ค ๋ณด๋‚ด๋Š” ์†Œ์ผ“ + ๋ฐ›๋Š” ์†Œ์ผ“ = 2๊ฐœ
file descriptor ์ถ”์ƒํ™”OS๋Š” ์†Œ์ผ“์„ ์ •์ˆ˜ fd๋กœ ๋…ธ์ถœ โ€” read/write/close๊ฐ€ ๊ทธ๋Œ€๋กœ ๋™์ž‘ (POSIX์˜ โ€œeverything is a fileโ€ ์ฒ ํ•™)

SOCKET ํƒ€์ž…์€ Windows์—์„  32/64๋น„ํŠธ ์ •์ˆ˜ ํ•ธ๋“ค, POSIX์—์„  int fd. ๊ทธ๋ž˜์„œ ํ‘œ์ค€ ์ž…์ถœ๋ ฅ(stdin/stdout)ยทํŒŒ์ผยทํŒŒ์ดํ”„ยท์†Œ์ผ“์ด ๋ชจ๋‘ ๊ฐ™์€ API๋กœ ๋‹ค๋ค„์ง„๋‹ค.

1
2
3
4
5
6
7
// POSIX โ€” ํŒŒ์ผ๊ณผ ์†Œ์ผ“ ๋ชจ๋‘ ๊ฐ™์€ read/write
int fd = open("file.txt", O_RDONLY);
read(fd, buf, sizeof(buf));

int sock = socket(AF_INET, SOCK_STREAM, 0);
// ... connect ํ›„
read(sock, buf, sizeof(buf));    // ๊ฐ™์€ read()!

์ด๊ฒŒ BSD socket API์˜ ์œ„๋Œ€ํ•œ ๋””์ž์ธ โ€” ํ†ต์‹ ์„ ํŒŒ์ผ I/O์™€ ๋˜‘๊ฐ™์ด ๋‹ค๋ฃจ๊ฒŒ ํ•œ๋‹ค.

1-2. ํ๋ฆ„ ํ•œ๋ˆˆ์— โ€” BSD socket API

1
2
3
4
5
6
7
8
9
10
11
12
์„œ๋ฒ„ ์ธก                          ํด๋ผ์ด์–ธํŠธ ์ธก
โ”€โ”€โ”€โ”€                             โ”€โ”€โ”€โ”€
socket()    โ†’ fd ์–ป๊ธฐ            socket()
bind()      โ†’ ์ฃผ์†Œ ๋ถ€์—ฌ
listen()    โ†’ ๋“ค์–ด์˜ค๋Š” ์—ฐ๊ฒฐ ๋Œ€๊ธฐ
                                 connect()  โ†’ ์—ฐ๊ฒฐ ์‹œ๋„
accept()    โ†’ ์ƒˆ ์—ฐ๊ฒฐ ์ˆ˜๋ฝ        โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
            (์ƒˆ ์†Œ์ผ“ fd ๋ฐ˜ํ™˜)
   โ†“                                 โ†“
send/recv โ†โ”€โ”€โ”€โ”€โ”€โ”€์–‘๋ฐฉํ–ฅโ”€โ”€โ”€โ”€โ”€โ†’ send/recv
   โ†“                                 โ†“
close()                           close()

๊ฐ ๋‹จ๊ณ„ ์˜๋ฏธ:

ํ•จ์ˆ˜์˜๋ฏธ
socket(family, type, proto)์ƒˆ ์†Œ์ผ“ fd ์ƒ์„ฑ. ๊ฐ€์กฑยทํƒ€์ž…ยทํ”„๋กœํ† ์ฝœ ์ง€์ •
bind(fd, addr, addrlen)์†Œ์ผ“์— ์ฃผ์†Œ(IP+ํฌํŠธ ๋˜๋Š” ๊ฒฝ๋กœ) ๋ถ€์—ฌ. ์„œ๋ฒ„ ํ•„์ˆ˜
listen(fd, backlog)TCP ์„œ๋ฒ„ โ€” ์—ฐ๊ฒฐ ๋Œ€๊ธฐ ์ƒํƒœ๋กœ. backlog๋Š” ๋ฏธ์ˆ˜๋ฝ ํ ๊นŠ์ด
accept(fd, ...)ํ์—์„œ ์—ฐ๊ฒฐ ํ•˜๋‚˜ ๊บผ๋‚ด ์ƒˆ fd ๋ฐ˜ํ™˜. ์ฐจ๋‹จํ˜•
connect(fd, addr, addrlen)ํด๋ผ์ด์–ธํŠธ โ€” ์„œ๋ฒ„์— ์—ฐ๊ฒฐ ์‹œ๋„
send/recv ๋˜๋Š” write/read๋ฐ์ดํ„ฐ ์†ก์ˆ˜์‹ 
close(fd)์†Œ์ผ“ ๋‹ซ์Œ. TCP๋Š” 4-way handshake

1-3. ์ข…๋ฅ˜ โ€” Stream vs Datagram

1
2
3
4
5
6
7
8
9
10
11
SOCK_STREAM (TCP):
   ๋ฐ”์ดํŠธ ์ŠคํŠธ๋ฆผ / ์—ฐ๊ฒฐ ์ง€ํ–ฅ / ์‹ ๋ขฐ์„ฑ / ์ˆœ์„œ ๋ณด์žฅ
   โ†’ ๊ฐ™์€ ์ฑ„๋„๋กœ 4๋ฐ”์ดํŠธ + 8๋ฐ”์ดํŠธ ์“ฐ๋ฉด 12๋ฐ”์ดํŠธ๋กœ ํ•œ ๋ฒˆ์— ๋ฐ›ํž ์ˆ˜ ์žˆ์Œ (๋ฉ”์‹œ์ง€ ๊ฒฝ๊ณ„ ์—†์Œ)

SOCK_DGRAM (UDP):
   ๋ฉ”์‹œ์ง€ ๋‹จ์œ„ / ๋น„์—ฐ๊ฒฐ / ๋น„์‹ ๋ขฐ / ์ˆœ์„œ ๋ณด์žฅ ์—†์Œ
   โ†’ 4๋ฐ”์ดํŠธ ํŒจํ‚ท + 8๋ฐ”์ดํŠธ ํŒจํ‚ท โ†’ 4๋ฐ”์ดํŠธ, 8๋ฐ”์ดํŠธ๋กœ ๋”ฐ๋กœ ๋ฐ›์Œ (๊ฒฝ๊ณ„ ๋ณด์กด)

SOCK_RAW:
   IP ํ—ค๋”๋ถ€ํ„ฐ ์ง์ ‘ โ€” ๋ณดํ†ต ๊ด€๋ฆฌ์ž ๊ถŒํ•œ ํ•„์š”
   โ†’ ping, traceroute, ํŒจํ‚ท ์บก์ฒ˜
ํƒ€์ž…์—ฐ๊ฒฐ์‹ ๋ขฐ์„ฑ์ˆœ์„œ๋ฉ”์‹œ์ง€ ๊ฒฝ๊ณ„๋น„์šฉ์‚ฌ์šฉ์ฒ˜
SOCK_STREAM (TCP)OO (์žฌ์ „์†ก)OXํ•ธ๋“œ์…ฐ์ดํฌ + ACKHTTPยทSSHยทDB
SOCK_DGRAM (UDP)XXXO๋‹จ์ˆœ ์†ก์ˆ˜์‹ DNSยท๊ฒŒ์ž„ยท์ŠคํŠธ๋ฆฌ๋ฐ
SOCK_SEQPACKETOOOO์ค‘๊ฐ„ํŠน์ˆ˜ (์ž˜ ์•ˆ ์”€)
SOCK_RAW-----ํŒจํ‚ท ์กฐ์ž‘ยท์ง„๋‹จ

1-4. ์ฃผ์†Œ ํŒจ๋ฐ€๋ฆฌ (family)

1
2
3
4
5
AF_INET    โ€” IPv4 (32๋น„ํŠธ IP + 16๋น„ํŠธ port)
AF_INET6   โ€” IPv6 (128๋น„ํŠธ IP + 16๋น„ํŠธ port)
AF_UNIX    โ€” UNIX domain (ํŒŒ์ผ ์‹œ์Šคํ…œ ๊ฒฝ๋กœ, ๊ฐ™์€ ๋จธ์‹ )
AF_BLUETOOTH โ€” Bluetooth
AF_PACKET  โ€” ๋งํฌ ๊ณ„์ธต (Linux, ํŒจํ‚ท ์บก์ฒ˜)
1
2
3
4
5
6
7
8
9
10
11
12
// IPv4 TCP
struct sockaddr_in addr = {
    .sin_family = AF_INET,
    .sin_port = htons(8080),
    .sin_addr.s_addr = inet_addr("127.0.0.1")
};

// UNIX domain
struct sockaddr_un addr = {
    .sun_family = AF_UNIX
};
strcpy(addr.sun_path, "/tmp/mysock");
ํŒจ๋ฐ€๋ฆฌ์ฃผ์†Œ๋ฒ”์œ„
AF_INETIPv4 + port๊ฐ™์€ ๋จธ์‹  (loopback) + ๋„คํŠธ์›Œํฌ
AF_INET6IPv6 + port๊ฐ™์€ ๋จธ์‹  + ๋„คํŠธ์›Œํฌ
AF_UNIXํŒŒ์ผ ๊ฒฝ๋กœ๊ฐ™์€ ๋จธ์‹ ๋งŒ (๊ฐ€์žฅ ๋น ๋ฆ„)

1-5. 5-tuple โ€” ์—ฐ๊ฒฐ์˜ ์‹๋ณ„์ž

TCP ์—ฐ๊ฒฐ ํ•˜๋‚˜๋Š” 5-tuple๋กœ ์œ ์ผํ•˜๊ฒŒ ์‹๋ณ„๋œ๋‹ค:

1
2
3
(protocol, src_ip, src_port, dst_ip, dst_port)

์˜ˆ: (TCP, 192.168.1.10:54321, 93.184.216.34:80)

๊ฐ™์€ ์„œ๋ฒ„ IPยทํฌํŠธ์— ์—ฌ๋Ÿฌ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋™์‹œ ์ ‘์†ํ•ด๋„, ํด๋ผ์ด์–ธํŠธ ์ธก ํฌํŠธ(ephemeral port, OS๊ฐ€ ์ž๋™ ํ• ๋‹น)๊ฐ€ ๋‹ค๋ฅด๋ฏ€๋กœ 5-tuple์ด ๋ชจ๋‘ ๋‹ค๋ฅด๋‹ค โ†’ ์ปค๋„์ด ๊ฐ ์—ฐ๊ฒฐ์„ ๋ถ„๋ฆฌ ๊ด€๋ฆฌ ๊ฐ€๋Šฅ.

1
2
3
4
์„œ๋ฒ„ 192.168.1.10:80
  โ”œโ”€ (TCP, 1.2.3.4:54321, 192.168.1.10:80)   โ† ์—ฐ๊ฒฐ 1
  โ”œโ”€ (TCP, 1.2.3.4:54322, 192.168.1.10:80)   โ† ๊ฐ™์€ IP์˜ ๋‹ค๋ฅธ ephemeral port
  โ””โ”€ (TCP, 5.6.7.8:39101, 192.168.1.10:80)   โ† ๋‹ค๋ฅธ ํด๋ผ์ด์–ธํŠธ

์ด๊ฒŒ ํ•œ ์„œ๋ฒ„๊ฐ€ ์ˆ˜์‹ญ๋งŒ ๋™์‹œ ์—ฐ๊ฒฐ์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ์›๋ฆฌ.

1-6. UNIX domain socket โ€” ๊ฐ™์€ ๋จธ์‹  IPC

22๋ฒˆ ยง10.2์˜ ํ•ต์‹ฌ ์žฌ์ •๋ฆฌ. ํŒŒ์ผ ์‹œ์Šคํ…œ ๊ฒฝ๋กœ๋กœ ์‹๋ณ„๋˜๊ณ , TCP loopback๋ณด๋‹ค 30~50% ๋น ๋ฅด๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// ์„œ๋ฒ„
int sfd = socket(AF_UNIX, SOCK_STREAM, 0);
struct sockaddr_un addr = { .sun_family = AF_UNIX };
strcpy(addr.sun_path, "/tmp/mysock");
unlink("/tmp/mysock");   // ์ด์ „ ์ž”์กด ํŒŒ์ผ ์ œ๊ฑฐ
bind(sfd, (struct sockaddr*)&addr, sizeof(addr));
listen(sfd, 5);
int cfd = accept(sfd, NULL, NULL);

// ํด๋ผ์ด์–ธํŠธ
int sfd = socket(AF_UNIX, SOCK_STREAM, 0);
struct sockaddr_un addr = { .sun_family = AF_UNIX };
strcpy(addr.sun_path, "/tmp/mysock");
connect(sfd, (struct sockaddr*)&addr, sizeof(addr));
write(sfd, "hello", 5);

ํŠน์ง•:

  • ํŒŒ์ผ ์‹œ์Šคํ…œ ๊ฒฝ๋กœ ์‹๋ณ„ โ€” /tmp/mysock, /var/run/docker.sock
  • ๊ถŒํ•œ ๊ด€๋ฆฌ โ€” chmod/chown ๊ทธ๋Œ€๋กœ ์ ์šฉ. ACL์ด OS ์ œ๊ณต
  • TCP๋ณด๋‹ค ๋น ๋ฆ„ โ€” ํ”„๋กœํ† ์ฝœ ์Šคํƒ(ํ—ค๋”ยท์ฒดํฌ์„ฌยท์‹œํ€€์Šค) ์šฐํšŒ
  • fd ์ „์†ก ๊ฐ€๋Šฅ โ€” SCM_RIGHTS๋กœ ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ ์ž์ฒด๋ฅผ ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค์— ์ „๋‹ฌ (๊ณ ๊ธ‰)
  • abstract socket (Linux) โ€” \0๋กœ ์‹œ์ž‘ํ•˜๋Š” ์ด๋ฆ„์œผ๋กœ ํŒŒ์ผ ์‹œ์Šคํ…œ ๋…ธ๋“œ ์—†์ด ์‚ฌ์šฉ

๋Œ€ํ‘œ ์‚ฌ์šฉ์ฒ˜:

  • Docker daemon (/var/run/docker.sock)
  • X11/Wayland ๋””์Šคํ”Œ๋ ˆ์ด ์„œ๋ฒ„
  • systemd activationยทjournald
  • DBus ๋ฐ์Šคํฌํ†ฑ IPC

1-7. loopback (127.0.0.1) vs UNIX domain

๊ฐ™์€ ๋จธ์‹  ์•ˆ์—์„œ TCP๋ฅผ ์“ธ ๋•Œ 127.0.0.1(IPv4 loopback) ๋˜๋Š” ::1(IPv6 loopback)์„ ์“ด๋‹ค. ์ปค๋„์ด NIC๋ฅผ ์šฐํšŒํ•ด ์ง์ ‘ ์ฒ˜๋ฆฌ.

ํ•ญ๋ชฉloopback (127.0.0.1 + TCP)UNIX domain (AF_UNIX)
์ฃผ์†Œ127.0.0.1:port/tmp/mysock (๊ฒฝ๋กœ)
ํ”„๋กœํ† ์ฝœ ์ŠคํƒTCP/IP ํ†ต๊ณผ (ํ—ค๋”ยท์ฒดํฌ์„ฌ)์šฐํšŒ (์ปค๋„ ์ง์ ‘ ํ)
์†๋„UNIX domain์˜ 70%100% (๊ธฐ์ค€)
๋ฒ„ํผ๋งํผ (TCP ์œˆ๋„์šฐ)์ž‘์Œ (์ปค๋„ ๋‚ด ๋ฒ„ํผ)
fd ์ „์†กXO (SCM_RIGHTS)
์ ‘๊ทผ ์ œ์–ด๋ฐฉํ™”๋ฒฝ ๊ทœ์น™ํŒŒ์ผ ์‹œ์Šคํ…œ ๊ถŒํ•œ
๋„คํŠธ์›Œํฌ ํ™•์žฅ๊ฐ™์€ ์ฝ”๋“œ๋กœ ์™ธ๋ถ€ ๊ฐ€๋Šฅ๊ฐ™์€ ๋จธ์‹ ๋งŒ
ํฌํŠธ ์ถฉ๋Œ65535๊ฐœ ํ•œ์ •๋ฌด๊ด€ (๊ฒฝ๋กœ)

๊ฒฐ๋ก  โ€” ๊ฐ™์€ ๋จธ์‹  ์•ˆ์—์„œ IPC๋งŒ ํ•„์š”ํ•˜๋ฉด UNIX domain์ด ๋น ๋ฅด๊ณ  ๊ถŒํ•œ ๊ด€๋ฆฌ ์‰ฌ์›€. ๋„คํŠธ์›Œํฌ ํ™•์žฅ ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์œผ๋ฉด ์ฒ˜์Œ๋ถ€ํ„ฐ TCP. Docker๊ฐ€ UNIX domain socket์„ ์“ฐ๋Š” ์ด์œ  โ€” ๋„คํŠธ์›Œํฌ ๋…ธ์ถœ ์œ„ํ—˜ ์—†์ด ํŒŒ์ผ ๊ถŒํ•œ์œผ๋กœ ์ ‘๊ทผ ์ œ์–ด.

1-8. Windows Winsock โ€” BSD socket์˜ Windows ๋ณ€ํ˜•

1
2
3
4
5
6
7
8
9
10
11
12
#include <winsock2.h>
#include <ws2tcpip.h>
#pragma comment(lib, "ws2_32.lib")

WSADATA wsa;
WSAStartup(MAKEWORD(2, 2), &wsa);   // โ† Windows๋งŒ ํ•„์ˆ˜

SOCKET s = socket(AF_INET, SOCK_STREAM, 0);
// ... bind/connect/send/recv ๋™์ผ
closesocket(s);                       // โ† close()๊ฐ€ ์•„๋‹ˆ๋ผ closesocket()

WSACleanup();

POSIX์™€์˜ ์ฐจ์ด:

ํ•ญ๋ชฉPOSIXWindows Winsock
์ดˆ๊ธฐํ™”์—†์ŒWSAStartup ํ•„์ˆ˜
์ข…๋ฃŒ์—†์ŒWSACleanup
fd ํƒ€์ž…intSOCKET (์ •์ˆ˜ ํ•ธ๋“ค)
๋‹ซ๊ธฐclose(fd)closesocket(s)
์—๋ŸฌerrnoWSAGetLastError()
non-blockingfcntl(F_SETFL, O_NONBLOCK)ioctlsocket(FIONBIO)
๊ณ ์„ฑ๋Šฅ ๋น„๋™๊ธฐepoll / kqueueIOCP (I/O Completion Port)
AF_UNIXํ‘œ์ค€Windows 10 1803+ ์ง€์› (์ด์ „์—” named pipe๋กœ ๋Œ€์ฒด)

Winsock์˜ IOCP๋Š” ๊ณ ์„ฑ๋Šฅ ์„œ๋ฒ„์˜ ์‚ฌ์‹ค์ƒ ํ‘œ์ค€ โ€” WSARecv/WSASend + completion port๋กœ ์ˆ˜์‹ญ๋งŒ ๋™์‹œ ์—ฐ๊ฒฐ ์ฒ˜๋ฆฌ. Linux์˜ epollยทBSD์˜ kqueue์™€ ๊ฐ™์€ ์—ญํ• .

1-9. IPC ๊ด€์ ์—์„œ ๋ณธ 22๋ฒˆ๊ณผ์˜ ์œ„์น˜

22๋ฒˆ ยง3 ๋ถ„๋ฅ˜ ํ‘œ๋ฅผ ๋‹ค์‹œ ์ ์šฉ:

๋ฉ”์ปค๋‹ˆ์ฆ˜๋ฐ์ดํ„ฐ/์‹ ํ˜ธ์ปค๋„ ๊ฒฝ์œ ๋„คํŠธ์›Œํฌ
UNIX domain socket๋ฐ์ดํ„ฐ๋งค๋ฒˆ๊ฐ™์€ ๋จธ์‹ 
TCP socket๋ฐ์ดํ„ฐ๋งค๋ฒˆO
UDP socket๋ฐ์ดํ„ฐ๋งค๋ฒˆO

์†Œ์ผ“์€ IPC ์นดํƒˆ๋กœ๊ทธ ์ค‘ โ€œ๋งค๋ฒˆ ์ปค๋„ ๊ฒฝ์œ  + ๋„คํŠธ์›Œํฌ ๊ฐ€๋Šฅโ€ ์ž๋ฆฌ์— ์œ„์น˜ํ•œ๋‹ค. ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ(๊ฐ€์žฅ ๋น ๋ฆ„)์™€ RPC(๊ฐ€์žฅ ๋А๋ฆผ) ์‚ฌ์ด์˜ ์ค‘๊ฐ„ ๋น„์šฉยท์ค‘๊ฐ„ ์ถ”์ƒํ™”ยท์ตœ๊ณ  ๋ฒ”์šฉ์„ฑ.

22๋ฒˆ ยง12 ๋น„์šฉ ํ‘œ ์žฌ์ธ์šฉ:

1
2
3
UNIX domain socket send/recv   ์ˆ˜ ฮผs
TCP loopback send/recv         5~30 ฮผs
TCP ๋„คํŠธ์›Œํฌ                    ์ˆ˜ ms (์ง€์—ฐ + ๋Œ€์—ญํญ)

๊ฐ™์€ ๋จธ์‹  ์•ˆ์—์„  ํŒŒ์ดํ”„์™€ ๋น„์Šทํ•œ ๋น„์šฉ, ๋„คํŠธ์›Œํฌ๋กœ ๊ฐ€๋ฉด ํ•œ ์ž๋ฆฟ์ˆ˜ ms๋กœ ์ฆ๊ฐ€. ๊ทธ๋ž˜์„œ โ€œ๊ฐ™์€ ๋จธ์‹  + ๋„คํŠธ์›Œํฌ ๊ฐ€๋Šฅ์„ฑ ๋ชจ๋‘ ๊ฐ€์ง„๋‹คโ€ ๊ฐ€ ์†Œ์ผ“์˜ ์ง„์งœ ๊ฐ€์น˜.

1-10. ํ”ํ•œ ํŒจํ„ด ์ฝ”๋“œ

1-10-1. TCP echo server (POSIX)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <string.h>

int main() {
    int sfd = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in addr = {
        .sin_family = AF_INET,
        .sin_port = htons(8080),
        .sin_addr.s_addr = INADDR_ANY
    };

    int opt = 1;
    setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));

    bind(sfd, (struct sockaddr*)&addr, sizeof(addr));
    listen(sfd, 5);

    while (1) {
        int cfd = accept(sfd, NULL, NULL);
        char buf[1024];
        ssize_t n = read(cfd, buf, sizeof(buf));
        if (n > 0) write(cfd, buf, n);   // echo
        close(cfd);
    }
    close(sfd);
}

1-10-2. UDP receiver

1
2
3
4
5
6
7
8
9
10
11
12
13
int sfd = socket(AF_INET, SOCK_DGRAM, 0);   // โ† SOCK_DGRAM
struct sockaddr_in addr = {
    .sin_family = AF_INET,
    .sin_port = htons(9000),
    .sin_addr.s_addr = INADDR_ANY
};
bind(sfd, (struct sockaddr*)&addr, sizeof(addr));

char buf[1024];
struct sockaddr_in from;
socklen_t fromlen = sizeof(from);
recvfrom(sfd, buf, sizeof(buf), 0, (struct sockaddr*)&from, &fromlen);
// UDP๋Š” connect/accept ์—†์ด recvfrom์œผ๋กœ ๋ˆ„๊ฐ€ ๋ณด๋ƒˆ๋Š”์ง€ ๋ฐ›์Œ

1-11. ๋ฉด์ ‘ ๋‹ต๋ณ€ ํ•œ ์ค„

โ€œ์†Œ์ผ“์€ ๋„คํŠธ์›Œํฌ ๋˜๋Š” ๊ฐ™์€ ๋จธ์‹  ์•ˆ์—์„œ ๋‘ endpoint๋ฅผ ์ž‡๋Š” ์–‘๋ฐฉํ–ฅ ํ†ต์‹  ์ฑ„๋„์˜ ์ถ”์ƒํ™”์ž…๋‹ˆ๋‹ค. OS๊ฐ€ ํŒŒ์ผ ๋””์Šคํฌ๋ฆฝํ„ฐ๋กœ ๋…ธ์ถœํ•ด ํŒŒ์ผ I/O์™€ ๊ฐ™์€ API(read/write)๋กœ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. ์ข…๋ฅ˜๋Š” stream(TCP)ยทdatagram(UDP)ยทraw ๋“ฑ์ด ์žˆ๊ณ , ์ฃผ์†Œ ํŒจ๋ฐ€๋ฆฌ๋กœ IPv4(AF_INET)ยทIPv6ยทUNIX domain(AF_UNIX)์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค. ๊ฐ™์€ ๋จธ์‹  IPC๋งŒ ํ•„์š”ํ•˜๋ฉด UNIX domain์ด TCP loopback๋ณด๋‹ค 30~50% ๋น ๋ฅด๊ณ  ํŒŒ์ผ ๊ถŒํ•œ์œผ๋กœ ์ ‘๊ทผ ์ œ์–ดํ•  ์ˆ˜ ์žˆ์–ด Docker ๋ฐ๋ชฌยทX11ยทsystemd ๊ฐ™์€ ์‹œ์Šคํ…œ ์„œ๋น„์Šค์—์„œ ํ‘œ์ค€์ž…๋‹ˆ๋‹ค. 22๋ฒˆ์—์„œ ๋ณธ IPC ์นดํƒˆ๋กœ๊ทธ ์ค‘ โ€˜๋งค๋ฒˆ ์ปค๋„ ๊ฒฝ์œ  + ๋„คํŠธ์›Œํฌ ๊ฐ€๋Šฅโ€™ ์ž๋ฆฌ์— ์žˆ๊ณ , ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ(์ˆ˜ ns)์™€ RPC(์ˆ˜์‹ญ~์ˆ˜๋ฐฑ ฮผs) ์‚ฌ์ด์˜ ์ค‘๊ฐ„ ๋น„์šฉยท์ตœ๊ณ  ๋ฒ”์šฉ์„ฑ์ด ์†Œ์ผ“์˜ ์ž๋ฆฌ์ž…๋‹ˆ๋‹ค.โ€


ํšŒ๊ท€ ๋‹ค๋ฆฌ

  • 22_ipc.md โ€” ๋ณธ ๋ฌธ์„œ์˜ ์›๋ณธ ยง10(์†Œ์ผ“), ยง3(๋ถ„๋ฅ˜์ถ•), ยง12(๋น„์šฉ ์ŠคํŽ™ํŠธ๋Ÿผ)์ด ๋‹ต๋ณ€ ๊ทผ๊ฑฐ.
  • 21_context_switching.md โ€” ๋งค ์†ก์ˆ˜์‹ ๋งˆ๋‹ค ๋ฐœ์ƒํ•˜๋Š” ๋ชจ๋“œ ์Šค์œ„์น˜ ๋น„์šฉ์ด ์†Œ์ผ“ ๋น„์šฉ์˜ ์ถœ๋ฐœ์ .
  • 19_process_vs_thread.md โ€” ์ฃผ์†Œ ๊ณต๊ฐ„ ๊ฒฉ๋ฆฌ๊ฐ€ IPC๊ฐ€ ํ•„์š”ํ•œ ์ด์œ ์˜ ํ† ๋Œ€.
  • 07_pointer_reference.md โ€” fd๋Š” ๊ฒฐ๊ตญ ์ปค๋„ ์ž๋ฃŒ๊ตฌ์กฐ์— ๋Œ€ํ•œ ํ•ธ๋“ค(์ถ”์ƒ ํฌ์ธํ„ฐ)์ด๋ผ๋Š” ์ ์—์„œ ๊ฐ™์€ ์ถ”์ƒํ™” ํŒจํ„ด.
์ด ๊ธฐ์‚ฌ๋Š” ์ €์ž‘๊ถŒ์ž์˜ CC BY 4.0 ๋ผ์ด์„ผ์Šค๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค.

ยฉ GoldBoll. ์ผ๋ถ€ ๊ถŒ๋ฆฌ ๋ณด์œ 

Powered by Jekyll with Chirpy theme

์ธ๊ธฐ ํƒœ๊ทธ