4 ๋ถ„ ์†Œ์š”

๋„คํŠธ์›Œํฌ ํ”„๋กœ๊ทธ๋ž˜๋ฐ

: ๋„คํŠธ์›Œํฌ๋กœ ์—ฐ๊ฒฐ๋œ ๋‘˜ ์ด์ƒ์˜ ์ปดํ“จํ„ฐ ์‚ฌ์ด์—์„œ ๋ฐ์ดํ„ฐ ์†ก์ˆ˜์‹  ํ”„๋กœ๊ทธ๋žจ ์ž‘์„ฑ ์˜๋ฏธ. ์†Œ์ผ“ ๊ธฐ๋ฐ˜์œผ๋กœ ํ”„๋กœ๊ทธ๋ž˜๋ฐ

์†Œ์ผ“ : ๋„คํŠธ์›Œํฌ ์—ฐ๊ฒฐ ๋„๊ตฌ

TCP๋ž€?

TCP (Transmission Control Protocol)

โ†’ ๋ฐ์ดํ„ฐ๋ฅผ ์•ˆ์ „ํ•˜๊ณ  ์ •ํ™•ํ•˜๊ฒŒ ์ฃผ๊ณ ๋ฐ›๊ธฐ ์œ„ํ•œ โ€œ์—ฐ๊ฒฐ์ง€ํ–ฅํ˜•โ€ ํ”„๋กœํ† ์ฝœ์ด์•ผ.

SOCKET_STREAM

โ€œ๋‚ด๊ฐ€ ๋ณด๋‚ธ ๋ฉ”์‹œ์ง€๊ฐ€ ์ž˜ ๋„์ฐฉํ–ˆ๋Š”์ง€ ํ™•์ธํ•˜๊ณ  ์‹ถ์–ด!โ€ โ†’ ๊ทธ๋Ÿด ๋•Œ๋Š” ๋ฌด์กฐ๊ฑด TCP

image

TCP ํ†ต์‹ ์˜ ํ๋ฆ„ ๊ตฌ์กฐ

๐Ÿ“ž TCP ํ†ต์‹ ์€ ์ „ํ™” ๊ฑฐ๋Š” ๊ณผ์ •์ด๋ž‘ ๋น„์Šทํ•จ.แŸ

  1. ์„œ๋ฒ„๋Š” ๋Œ€๊ธฐ ์ค‘ (์ „ํ™” ๋ฐ›์„ ์ค€๋น„)
  2. ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ „ํ™”ํ•จ (์—ฐ๊ฒฐ ์š”์ฒญ)
  3. ์„œ๋ฒ„๊ฐ€ ๋ฐ›์Œ (์—ฐ๊ฒฐ ์ˆ˜๋ฝ)
  4. ๋‘˜์ด ํ†ตํ™”ํ•จ (๋ฐ์ดํ„ฐ ์†ก์ˆ˜์‹ )
  5. ํ•œ์ชฝ์ด ๋Š์Œ (์ข…๋ฃŒ)

** ์„œ๋ฒ„ ์ž…์žฅ**

socket()      // ์ „ํ™”๊ธฐ ์žฅ๋งŒ
bind()        // ์ „ํ™”๋ฒˆํ˜ธ ๋“ฑ๋ก (IP + PORT)
listen()      // ์ „ํ™” ๋ฐ›์„ ์ค€๋น„ ์™„๋ฃŒ
accept()      // ์ „ํ™” ๋ฐ›๊ธฐ
read()/write() // ํ†ตํ™” (๋ฐ์ดํ„ฐ ์ฃผ๊ณ ๋ฐ›๊ธฐ)

** ํด๋ผ์ด์–ธํŠธ ์ž…์žฅ**

socket()      // ์ „ํ™”๊ธฐ ์žฅ๋งŒ
connect()     // ์ „ํ™” ๊ฑธ๊ธฐ
read()/write() // ํ†ตํ™” (๋ฐ์ดํ„ฐ ์ฃผ๊ณ ๋ฐ›๊ธฐ)

image

์ธํ„ฐ๋„ท ์ฃผ์†Œ & ํฌํŠธ

** IP ์ฃผ์†Œ?**

  • ์ธํ„ฐ๋„ท์ƒ์—์„œ ์ปดํ“จํ„ฐ๋ฅผ ์‹๋ณ„ํ•˜๊ธฐ ์œ„ํ•œ ์ฃผ์†Œ
  • IPv4 (4๋ฐ”์ดํŠธ), IPv6 (16๋ฐ”์ดํŠธ)

** PORT ๋ฒˆํ˜ธ?**

  • ํ•œ ์ปดํ“จํ„ฐ ๋‚ด์—์„œ ์†Œ์ผ“์„ ๊ตฌ๋ถ„ํ•˜๊ธฐ ์œ„ํ•œ ๋ฒˆํ˜ธ
  • 065535 (01023์€ well-known ํฌํŠธ)

๊ตฌ์กฐ์ฒด sockaddr_in ์„ค๋ช…

  • sin_family: ์ฃผ์†Œ ์ฒด๊ณ„ (AF_INET ๋“ฑ)
  • sin_port: ํฌํŠธ ๋ฒˆํ˜ธ (๋„คํŠธ์›Œํฌ ๋ฐ”์ดํŠธ ์ˆœ์„œ)
  • sin_addr: IP ์ฃผ์†Œ
  • sin_zero: ์˜๋ฏธ ์—†์Œ, 0์œผ๋กœ ์ฑ„์›€

๋ฐ”์ดํŠธ ์ˆœ์„œ & ๋„คํŠธ์›Œํฌ ๋ฐ”์ดํŠธ ์ˆœ์„œ

** ๋น… ์—”๋””์•ˆ (Big Endian)**

  • ์ƒ์œ„ ๋ฐ”์ดํŠธ๋ฅผ ์ž‘์€ ๋ฒˆ์ง€์ˆ˜์— ์ €์žฅ (๋„คํŠธ์›Œํฌ ๊ธฐ์ค€)
  • ์˜ˆ: 0x12345678 โ†’ 12๊ฐ€ ๊ฐ€์žฅ ์•ž์—

** ๋ฆฌํ‹€ ์—”๋””์•ˆ (Little Endian)**

  • ์ƒ์œ„ ๋ฐ”์ดํŠธ๋ฅผ ํฐ ๋ฒˆ์ง€์ˆ˜์— ์ €์žฅ
  • ์˜ˆ: 0x12345678 โ†’ 78์ด ๊ฐ€์žฅ ์•ž์—

** ํ˜ธ์ŠคํŠธ ๋ฐ”์ดํŠธ ์ˆœ์„œ**

  • CPU๋ณ„ ๋ฐ์ดํ„ฐ ์ €์žฅ ๋ฐฉ์‹ (OS๋‚˜ ์ปดํ“จํ„ฐ ๊ตฌ์กฐ์— ๋”ฐ๋ผ ๋‹ค๋ฆ„)

** ๋„คํŠธ์›Œํฌ ๋ฐ”์ดํŠธ ์ˆœ์„œ**

  • ํ†ต์‹  ํ‘œ์ค€
  • ํ•ญ์ƒ ๋น… ์—”๋””์•ˆ์„ ๊ธฐ์ค€

    โ†’ ๋ฐ์ดํ„ฐ ์ „์†ก ์ „์— ๋ฐ˜๋“œ์‹œ ํ˜ธ์ŠคํŠธ ๋ฐ”์ดํŠธ ์ˆœ์„œ๋ฅผ ๋„คํŠธ์›Œํฌ ๋ฐ”์ดํŠธ ์ˆœ์„œ๋กœ ๋ณ€ํ™˜ํ•ด์•ผ ํ•จ!


** ๋ฐ”์ดํŠธ ์ˆœ์„œ ๋ณ€ํ™˜ ํ•จ์ˆ˜**

ํ•จ์ˆ˜ ์—ญํ• 
htons() host(๋ฆฌํ‹€ ์—”๋””์•ˆ)โ†’ network(๋น… ์—”๋””์•ˆ) (shortํ˜• == 16๋น„ํŠธ) / ์ฒ˜์Œ๋ถ€ํ„ฐ ๋น… ์—”๋””์•ˆ ์ผ์‹œ ๊ทธ๋ƒฅ ๋น… ์—”๋””์•ˆ ์œ ์ง€
htonl() host โ†’ network (longํ˜• == 32๋น„ํŠธ)
ntohs() network โ†’ host (shortํ˜•)
ntohl() network โ†’ host (longํ˜•)

** ์ฃผ์†Œ ๋ณ€ํ™˜ ๊ด€๋ จ ํ•จ์ˆ˜**

** inet_addr()**

  • โ€œ127.0.0.1โ€ ๊ฐ™์€ ๋ฌธ์ž์—ด IP โ†’ 4๋ฐ”์ดํŠธ ์ˆซ์ž๋กœ ๋ณ€ํ™˜
  • ๊ฒฐ๊ณผ: ์ •์ˆ˜ํ˜• IP ์ฃผ์†Œ ๋ฐ˜ํ™˜
  • ๋‹จ, byte ์ˆœ์„œ๋ฅผ ๋ฐ”๊ฟ”์„œ ์ €์žฅํ•จ (์ฃผ์˜!)

** inet_aton()**

  • ์œ„ ํ•จ์ˆ˜์™€ ๋™์ผํ•œ ์—ญํ•  (๋” ์•ˆ์ „ํ•˜๊ณ  ์—„๊ฒฉํ•œ ๋ฒ„์ „)
  • ๊ฐ’์„ ์ €์žฅํ•œ๋‹ค๋Š” ์ ์—์„œ ์ฐจ์ด
  • ๋ฆฌํ„ด๊ฐ’: ์„ฑ๊ณต ์—ฌ๋ถ€ (์ •์ˆ˜)

** inet_ntoa()**

  • ์ˆซ์ž ํ˜•ํƒœ์˜ IP ์ฃผ์†Œ โ†’ ๋ฌธ์ž์—ด๋กœ ๋‹ค์‹œ ๋ฐ”๊ฟ”์คŒ
  • IP๋ฅผ ์‚ฌ๋žŒ์ด ์ฝ์„ ์ˆ˜ ์žˆ๋„๋ก ํ‘œ์‹œ

  • WSAStringToAddress
    • inet_addr๊ณผ ๋น„์Šทํ•˜์ง€๋งŒ, ์ฃผ์†Œ์™€ ํฌํŠธ๋ฒˆํ˜ธ๊ฐ€ ๊ฐ™์ด ์žˆ๋Š”๊ฑฐ ํ—ˆ์šฉ (1.2.3.4:9000)
  • WSAAddressToString
    • inet_ntoa์™€ ๋น„์Šทํ•˜์ง€๋งŒ, ์ฃผ์†Œ์™€ ํฌํŠธ๋ฒˆํ˜ธ๊ฐ€ ๊ฐ™์ด ์žˆ๋Š”๊ฑฐ ํ—ˆ์šฉ (1.2.3.4:9000)

** sockaddr ๊ตฌ์กฐ์ฒด์™€ ์ฃผ์†Œ ์„ค์ •**

struct sockaddr_in์„ ์‚ฌ์šฉํ•  ๋•Œ ์ฃผ์˜์‚ฌํ•ญ

  • IPv4์šฉ ์†Œ์ผ“ ์ฃผ์†Œ๋Š” SOCKADDR_IN์œผ๋กœ ์ •์˜
  • bind ์‹œ์—๋Š” sockaddr*๋กœ ์บ์ŠคํŒ…ํ•ด์„œ ์‚ฌ์šฉํ•ด์•ผ ํ•จ
struct sockaddr_in serv_addr;
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); // ๋ชจ๋“  IP ํ—ˆ์šฉ
serv_addr.sin_port = htons(atoi(serv_port));

** INADDR_ANY?**

  • ํ˜„์žฌ ์‹คํ–‰ ์ค‘์ธ ์ปดํ“จํ„ฐ์˜ ๋ชจ๋“  IP ์ฃผ์†Œ์—์„œ ์ ‘๊ทผ ๊ฐ€๋Šฅ
  • ์„œ๋ฒ„์—์„œ ํด๋ผ์ด์–ธํŠธ ์š”์ฒญ์„ ๋‹ค ์ˆ˜๋ฝํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ค์ •ํ•˜๋Š” ์ƒ์ˆ˜

** ์„œ๋ฒ„ ์ฃผ์†Œ ๋ฐ”์ธ๋”ฉ ์˜ˆ์‹œ**

int serv_sock;
struct sockaddr_in serv_addr;
char* serv_port = "9190";

// ์†Œ์ผ“ ์ƒ์„ฑ
serv_sock = socket(PF_INET, SOCK_STREAM, 0);

// ์ฃผ์†Œ ์„ค์ •
memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(atoi(serv_port));

// ๋ฐ”์ธ๋”ฉ
bind(serv_sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr));

** ์ด๊ฑด TCP ์„œ๋ฒ„์—์„œ ๊ธฐ๋ณธ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ํฌ๋งท!**


UDP (User Datagram Protocol)

TCP์™€ UDP ๋น„๊ต

  • UDP๋Š” ๋น„์—ฐ๊ฒฐํ˜• ํ”„๋กœํ† ์ฝœ๋กœ TCP์™€ ๋‹ค๋ฅด๊ฒŒ ์—ฐ๊ฒฐ ๊ฐœ๋… ์—†์Œ
  • ํ™•์ธ ๋ฉ”์‹œ์ง€(SEQ, ACK) ์—†์Œ โ†’ Flow Control ์—†์Œ
  • ๋ฐ์ดํ„ฐ ์ „์†ก ์ˆœ์„œ ๋ฐ ์†์‹ค์— ๋Œ€ํ•œ ๋ณด์žฅ X
  • ์‹ค์‹œ๊ฐ„์„ฑ์ด ์ค‘์š”ํ•œ ์„œ๋น„์Šค์— ์ ํ•ฉ (์Œ์„ฑ, ์˜์ƒ ๋“ฑ)
  • SOCKET_DGRAM

โš™๏ธ UDP ์ฃผ์š” ํ•จ์ˆ˜ ์„ค๋ช…

** recvfrom() ํ•จ์ˆ˜**

  • ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์‹ ํ•˜๊ณ  ์†ก์‹ ์ž ์ •๋ณด๋„ ํ•จ๊ป˜ ์ „๋‹ฌ๋ฐ›์Œ
  • ์ฃผ์š” ํŒŒ๋ผ๋ฏธํ„ฐ:
    • from: ๋ณด๋‚ธ ์ธก ์ฃผ์†Œ ์ •๋ณด ์ €์žฅํ•  ๊ตฌ์กฐ์ฒด
    • addrlen: ์ฃผ์†Œ ๊ธธ์ด
  • ์—ฐ๊ฒฐ ๊ฐœ๋… ์—†์Œ โ†’ ๋งค๋ฒˆ ์ˆ˜์‹ ํ•  ๋•Œ ์†ก์‹ ์ž ์ •๋ณด ํฌํ•จ ํ•„์š”

** sendto() ํ•จ์ˆ˜**

  • ๋ฐ์ดํ„ฐ๋ฅผ ์†ก์‹ ํ•˜๋ฉฐ ์ˆ˜์‹ ์ž ์ฃผ์†Œ๋ฅผ ๋ช…์‹œ
  • ์ฃผ์š” ํŒŒ๋ผ๋ฏธํ„ฐ:
    • to: ๋ฐ›์„ ์ธก ์ฃผ์†Œ ์ •๋ณด
    • addrlen: ์ฃผ์†Œ ๊ตฌ์กฐ์ฒด์˜ ํฌ๊ธฐ

์š”์•ฝ: recvfrom์€ ๋ˆ„๊ฐ€ ๋ณด๋ƒˆ๋Š”์ง€ ์•Œ๋ ค์ฃผ๊ณ , sendto๋Š” ์–ด๋””๋กœ ๋ณด๋‚ผ์ง€ ์ง์ ‘ ์ง€์ •


** UDP์˜ ๋ฐ์ดํ„ฐ ๊ฒฝ๊ณ„ ์ฒ˜๋ฆฌ**

  • UDP๋Š” ๋ฐ์ดํ„ฐ ๋‹จ์œ„(ํŒจํ‚ท) ๊ฒฝ๊ณ„๊ฐ€ ์กด์žฌ
  • recvfrom()์„ ํ˜ธ์ถœํ•  ๋•Œ๋งˆ๋‹ค ํ•œ ๊ฐœ์˜ ํŒจํ‚ท๋งŒ ์ˆ˜์‹ ๋จ
  • ์˜ˆ: sleep() ์ค‘์—๋„ ๋ฉ”์‹œ์ง€๊ฐ€ ์˜ค๋ฉด 3๊ฐœ ์ค‘ 3๊ฐœ ๋ชจ๋‘ ๊ฐœ๋ณ„๋กœ ๋„์ฐฉํ•จ

    โ†’ TCP์™€ ๋‹ฌ๋ฆฌ ๋ญ‰์ณ์„œ ์˜ค๋Š” ๊ฒŒ ์•„๋‹˜


** UDP vs TCP ํ•จ์ˆ˜ ์ฐจ์ด**

  • TCP๋Š” ์—ฐ๊ฒฐ ๊ธฐ๋ฐ˜์ด๋ผ send, recv๋งŒ ์“ฐ๊ณ  ๋Œ€์ƒ ์ง€์ • X
  • UDP๋Š” ๋น„์—ฐ๊ฒฐ์ด๋ฏ€๋กœ sendto, recvfrom์œผ๋กœ ๋งค๋ฒˆ ์ฃผ์†Œ ์ง€์ • ํ•„์š”

** Connected UDP ์†Œ์ผ“?**

  • connected UDP ์†Œ์ผ“์€ TCP์ฒ˜๋Ÿผ ์—ฐ๊ฒฐ๋œ ๊ฑด ์•„๋‹ˆ์ง€๋งŒ
  • ์†Œ์ผ“์˜ ๋ชฉ์ ์ง€๋ฅผ ๋ฏธ๋ฆฌ ์„ค์ •ํ•œ ์ƒํƒœ
  • ์ดํ›„์—” send, recv๋กœ๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅ (์ฃผ์†Œ ๋งค๋ฒˆ ์ง€์ • ์•ˆ ํ•ด๋„ ๋จ)

** ์–‘๋ฐฉํ–ฅ ํ†ต์‹ : ์—์ฝ” ์„œ๋ฒ„ & ํด๋ผ์ด์–ธํŠธ**

์—์ฝ” ํ†ต์‹ ์ด๋ž€?

ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์ž…๋ ฅํ•œ ๋ฌธ์ž์—ด์„ ์„œ๋ฒ„๊ฐ€ ๊ทธ๋Œ€๋กœ ๋ฐ›์•„์„œ ๋Œ๋ ค๋ณด๋‚ด๋Š” ๊ตฌ์กฐ

image

๐Ÿ”šย ์†Œ์ผ“์˜ ์šฐ์•„ํ•œ ์ข…๋ฃŒ (Half-Close & shutdown())

** ์ผ๋ฐ˜์ ์ธ close()์˜ ํ•œ๊ณ„**

  • ์šฐ๋ฆฌ๊ฐ€ ํ‰์†Œ์— ์“ฐ๋˜ close()๋Š” ์–‘์ชฝ ์ŠคํŠธ๋ฆผ ๋ชจ๋‘ ์ข…๋ฃŒํ•จ
  • ๋ฌธ์ œ๋Š”?

    โ†’ ์ƒ๋Œ€๋ฐฉ์ด ์•„์ง ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๋‚ด๊ณ  ์žˆ์„ ์ˆ˜๋„ ์žˆ์Œ

    โ†’ ์ผ๋ฐฉ์ ์ธ ์ข…๋ฃŒ๋กœ ๋ฐ์ดํ„ฐ ์œ ์‹ค ๊ฐ€๋Šฅ์„ฑ ์žˆ์Œ

** Half-Close**

  • TCP๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์ฃผ๊ณ ๋ฐ›๋Š” ๋ฐฉํ–ฅ์ด ๋”ฐ๋กœ ์žˆ์Œ
  • โ†’ ๊ทธ๋Ÿผ ์ฝ๊ธฐ๋งŒ ๋Š๊ฑฐ๋‚˜, ์“ฐ๊ธฐ๋งŒ ๋Š๋Š” ๊ฒŒ ๊ฐ€๋Šฅํ•˜์ง€ ์•Š์„๊นŒ?

์ด๊ฑธ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ด์ฃผ๋Š” ํ•จ์ˆ˜๊ฐ€ ๋ฐ”๋กœ shutdown()

์ž…๋ ฅ ์ŠคํŠธ๋ฆผ ๋งŒ ์ข…๋ฃŒ / ์ถœ๋ ฅ ์ŠคํŠธ๋ฆผ ๋งŒ ์ข…๋ฃŒ ๊ฐ€๋Šฅ

image

๋„๋ฉ”์ธ

์šฐ๋ฆฌ๊ฐ€ ํ”ํžˆ ์ ‘ํ•˜๋Š” ์›น ์ฃผ์†Œ: www.google.com, www.naver.com ๊ฐ™์€ ๊ฒƒ๋“ค

์ด๊ฑด ์‚ฌ๋žŒ์ด ๋ณด๊ธฐ ์‰ฝ๊ฒŒ ๋งŒ๋“  ์ฃผ์†Œ์ž„

์‹ค์ œ ํ†ต์‹ ์€ IP ์ฃผ์†Œ(์ˆซ์ž) ๊ธฐ๋ฐ˜์œผ๋กœ ์ด๋ฃจ์–ด์ง

๊ทธ๋ž˜์„œ ๋„๋ฉ”์ธ โ†’ IP ์ฃผ์†Œ ์ด๊ฑธ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒŒ DNS (Domain Name System)

** DNS์˜ ์—ญํ• **

๋„๋ฉ”์ธ ์ด๋ฆ„์„ IP ์ฃผ์†Œ๋กœ ๋ฐ”๊ฟ”์ฃผ๋Š” ์‹œ์Šคํ…œ

** ๋„๋ฉ”์ธ โ†’ IP๋กœ ๋ฐ”๊พธ๊ธฐ:ย gethostbyname()**


struct hostent* gethostbyname(const char* name);

IP โ†’ ๋„๋ฉ”์ธ์œผ๋กœ ๋ฐ”๊พธ๊ธฐ:ย gethostbyaddr()

struct hostent* gethostbyaddr(const void* addr, socklen_t len, int type);

gethostbyname()์€ DNS์˜ ์ข…๋ฅ˜์ธ๊ฐ€?

โ†’ ์•„๋‹˜!

gethostbyname์€ DNS์˜ ์ข…๋ฅ˜๊ฐ€ ์•„๋‹ˆ๋ผ, DNS๋ฅผ ์‚ฌ์šฉํ•˜๋Š” Cํ•จ์ˆ˜ ์ค‘ ํ•˜๋‚˜

gethostbyaddr()์€ ๋ฐฉํ–ฅ์ด ๋ฐ˜๋Œ€

IP ์ฃผ์†Œ์˜ ์—ญ๋ฐฉํ–ฅ ์กฐํšŒ(Reverse DNS Lookup) ์—ญํ• 

</aside>

ํƒœ๊ทธ:

์นดํ…Œ๊ณ ๋ฆฌ:

์—…๋ฐ์ดํŠธ: