๐ ๋คํธ์ํฌํ๋ก๊ทธ๋๋ฐ ์ค๊ฐ๊ณ ์ฌ ์ ๋ฆฌ
๋คํธ์ํฌ ํ๋ก๊ทธ๋๋ฐ
: ๋คํธ์ํฌ๋ก ์ฐ๊ฒฐ๋ ๋ ์ด์์ ์ปดํจํฐ ์ฌ์ด์์ ๋ฐ์ดํฐ ์ก์์ ํ๋ก๊ทธ๋จ ์์ฑ ์๋ฏธ. ์์ผ ๊ธฐ๋ฐ์ผ๋ก ํ๋ก๊ทธ๋๋ฐ
์์ผ : ๋คํธ์ํฌ ์ฐ๊ฒฐ ๋๊ตฌ
TCP๋?
TCP (Transmission Control Protocol)
โ ๋ฐ์ดํฐ๋ฅผ ์์ ํ๊ณ ์ ํํ๊ฒ ์ฃผ๊ณ ๋ฐ๊ธฐ ์ํ โ์ฐ๊ฒฐ์งํฅํโ ํ๋กํ ์ฝ์ด์ผ.
SOCKET_STREAM
โ๋ด๊ฐ ๋ณด๋ธ ๋ฉ์์ง๊ฐ ์ ๋์ฐฉํ๋์ง ํ์ธํ๊ณ ์ถ์ด!โ โ ๊ทธ๋ด ๋๋ ๋ฌด์กฐ๊ฑด TCP
TCP ํต์ ์ ํ๋ฆ ๊ตฌ์กฐ
๐ TCP ํต์ ์ ์ ํ ๊ฑฐ๋ ๊ณผ์ ์ด๋ ๋น์ทํจ.แ
- ์๋ฒ๋ ๋๊ธฐ ์ค (์ ํ ๋ฐ์ ์ค๋น)
- ํด๋ผ์ด์ธํธ๊ฐ ์ ํํจ (์ฐ๊ฒฐ ์์ฒญ)
- ์๋ฒ๊ฐ ๋ฐ์ (์ฐ๊ฒฐ ์๋ฝ)
- ๋์ด ํตํํจ (๋ฐ์ดํฐ ์ก์์ )
- ํ์ชฝ์ด ๋์ (์ข ๋ฃ)
** ์๋ฒ ์ ์ฅ**
socket() // ์ ํ๊ธฐ ์ฅ๋ง
bind() // ์ ํ๋ฒํธ ๋ฑ๋ก (IP + PORT)
listen() // ์ ํ ๋ฐ์ ์ค๋น ์๋ฃ
accept() // ์ ํ ๋ฐ๊ธฐ
read()/write() // ํตํ (๋ฐ์ดํฐ ์ฃผ๊ณ ๋ฐ๊ธฐ)
** ํด๋ผ์ด์ธํธ ์ ์ฅ**
socket() // ์ ํ๊ธฐ ์ฅ๋ง
connect() // ์ ํ ๊ฑธ๊ธฐ
read()/write() // ํตํ (๋ฐ์ดํฐ ์ฃผ๊ณ ๋ฐ๊ธฐ)
์ธํฐ๋ท ์ฃผ์ & ํฌํธ
** 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๋ก๋ง ์ฌ์ฉ ๊ฐ๋ฅ (์ฃผ์ ๋งค๋ฒ ์ง์ ์ ํด๋ ๋จ)
** ์๋ฐฉํฅ ํต์ : ์์ฝ ์๋ฒ & ํด๋ผ์ด์ธํธ**
์์ฝ ํต์ ์ด๋?
ํด๋ผ์ด์ธํธ๊ฐ ์ ๋ ฅํ ๋ฌธ์์ด์ ์๋ฒ๊ฐ ๊ทธ๋๋ก ๋ฐ์์ ๋๋ ค๋ณด๋ด๋ ๊ตฌ์กฐ
๐ย ์์ผ์ ์ฐ์ํ ์ข ๋ฃ (Half-Close & shutdown())
** ์ผ๋ฐ์ ์ธ close()์ ํ๊ณ**
- ์ฐ๋ฆฌ๊ฐ ํ์์ ์ฐ๋ close()๋ ์์ชฝ ์คํธ๋ฆผ ๋ชจ๋ ์ข ๋ฃํจ
-
๋ฌธ์ ๋?
โ ์๋๋ฐฉ์ด ์์ง ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ด๊ณ ์์ ์๋ ์์
โ ์ผ๋ฐฉ์ ์ธ ์ข ๋ฃ๋ก ๋ฐ์ดํฐ ์ ์ค ๊ฐ๋ฅ์ฑ ์์
** Half-Close**
- TCP๋ ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ๋ ๋ฐฉํฅ์ด ๋ฐ๋ก ์์
- โ ๊ทธ๋ผ ์ฝ๊ธฐ๋ง ๋๊ฑฐ๋, ์ฐ๊ธฐ๋ง ๋๋ ๊ฒ ๊ฐ๋ฅํ์ง ์์๊น?
์ด๊ฑธ ๊ฐ๋ฅํ๊ฒ ํด์ฃผ๋ ํจ์๊ฐ ๋ฐ๋ก shutdown()
์ ๋ ฅ ์คํธ๋ฆผ ๋ง ์ข ๋ฃ / ์ถ๋ ฅ ์คํธ๋ฆผ ๋ง ์ข ๋ฃ ๊ฐ๋ฅ
๋๋ฉ์ธ
์ฐ๋ฆฌ๊ฐ ํํ ์ ํ๋ ์น ์ฃผ์: 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>