μμΌ νλ‘κ·Έλλ°μ μμ: μ£Όμ 체κ³λΆν° closesocketκΉμ§ νλμ 보기
λ¨μν λμ μ΄ν΄λΏλ§ μλλΌ, μ€λ₯ μ²λ¦¬ νλ¦, μ μ λ³μ νμ©, Winsock νμ₯ ν¨μ μ μ©λ²κΉμ§ μ€λ¬΄μ μΈ μΈ‘λ©΄μ κ³ λ €ν΄ μ 리νλ€.
β μ°μ΅λ¬Έμ 05-B: μ¬μ©μ μ μ ν¨μμ μ€λ₯ μ²λ¦¬
π§ μꡬ μ¬ν μμ½
- f(int x) ν¨μλ xκ° μμλ©΄ μ€ν¨, κ·Έλ μ§ μμΌλ©΄ μ±κ³΅
- μ€ν¨ μ errno μ μ λ³μμ EINVAL μ€μ
- λ¦¬ν΄ κ°μ μ±κ³΅ μ 0, μ€ν¨ μ 1
π ꡬν μ½λ μμ
c
볡μ¬νΈμ§
#include <stdio.h>
#include <errno.h> // errno, EINVAL
#include <stdlib.h> // exit()
void err_quit(const char* msg) {
perror(msg);
exit(1);
}
int f(int x) {
if (x >= 0) {
errno = 0;
return 0;
} else {
errno = EINVAL; // Invalid argument
return -1;
}
}
int main() {
int retval = f(-100); // μ€ν¨ μλ
if (retval < 0)
err_quit("f()");
return 0;
}
π‘ μ€ν κ²°κ³Ό μμ
plaintext
볡μ¬νΈμ§
f(): Invalid argument
errnoλ C νμ€μ μ μ μ€λ₯ μ½λ λ³μμ΄λ©°, μμ€ν νΈμΆ μ€λ₯ μΈμλ μ¬μ©μ μ μ ν¨μμμ λμΌν λ°©μμΌλ‘ μ²λ¦¬ κ°λ₯νλ€.
β μ°μ΅λ¬Έμ 06: WSASocket()μΌλ‘ TCP / UDP μμΌ μμ±
π κ°μ
**WSASocket()**μ **socket()**κ³Ό μ μ¬νμ§λ§ νμ₯ μ΅μ , μ€λ²λ© IO, νλκ·Έ μ§μ μ΄ κ°λ₯ν Winsock κ³ κΈ ν¨μλ€.
π§ κΈ°λ³Έ μ¬μ© νμ
c
볡μ¬νΈμ§
SOCKET WSASocket(
int af, // μ£Όμ μ²΄κ³ (μ: AF_INET)
int type, // μμΌ νμ
(μ: SOCK_STREAM)
int protocol, // νλ‘ν μ½ (μ: IPPROTO_TCP)
LPWSAPROTOCOL_INFO lpProtocolInfo,
GROUP g,
DWORD dwFlags // μ΅μ
νλκ·Έ
);
π TCP/UDP μμΌ μμ± μμ μ½λ
c
볡μ¬νΈμ§
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#pragma comment(lib, "ws2_32")
void err_quit(const char* msg) {
fprintf(stderr, "[μ€λ₯] %s: %d\\n", msg, WSAGetLastError());
exit(1);
}
int main() {
WSADATA wsa;
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
err_quit("WSAStartup()");
// TCP μμΌ
SOCKET tcp_sock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0);
if (tcp_sock == INVALID_SOCKET)
err_quit("WSASocket() - TCP");
// UDP μμΌ
SOCKET udp_sock = WSASocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, NULL, 0, 0);
if (udp_sock == INVALID_SOCKET)
err_quit("WSASocket() - UDP");
printf("TCP μμΌ: %d\\n", (int)tcp_sock);
printf("UDP μμΌ: %d\\n", (int)udp_sock);
closesocket(tcp_sock);
closesocket(udp_sock);
WSACleanup();
return 0;
}
β ν΅μ¬ μ°¨μ΄μ μμ½: socket() vs WSASocket()
νλͺ© socket() WSASocket()
κΈ°λ³Έ μ©λ | λ¨μ μμΌ μμ± | κ³ κΈ κΈ°λ₯ μ€μ μ΄ νμν μμΌ μμ± |
νμ₯ μ΅μ | λΆκ° | dwFlags νλκ·Έλ‘ μ€μ κ°λ₯ (μ: μ€λ²λ©) |
νμ© μν© | λ¨μ ν΅μ νλ‘κ·Έλ¨ | κ³ μ±λ₯ μλ², Overlapped I/O, QoS λ± νμμ |
μ΄ μΉμ μμλ λ€νΈμν¬ νλ‘κ·Έλλ°μμ κ°μ₯ μ€μν κΈ°λ° μ€ νλμΈ "μ€λ₯ μ²λ¦¬(Error Handling)" κ°λ μ λ€λ£¬λ€. νΉν μμΌ ν¨μμ μ€ν¨ κ°λ₯μ±μ΄ λμ λ§νΌ, μλμ°/리λ μ€ νκ²½μμ μ€λ₯λ₯Ό μ νν νμ§νκ³ , μ¬μ©μμκ² λͺ νν μ λ¬νλ λ‘μ§μ μ€λ¬΄μμ λ§€μ° μ€μνλ€.
β Chapter 02 - 01: μ€λ₯ μ²λ¦¬ ν΅μ¬ μ 리
π λ€νΈμν¬ νλ‘κ·Έλλ°μμ μ€λ₯ μ²λ¦¬κ° μ€μν μ΄μ
- λ€νΈμν¬λ μμΈ‘ λΆκ°λ₯ν μΈλΆ νκ²½μ μμ‘΄ (μΌμ΄λΈ, λΌμ°ν°, ν¬νΈ, λ°©νλ²½ λ±)
- ν¨μ νΈμΆμ΄ μ€ν¨ν κ°λ₯μ±μ΄ λκΈ° λλ¬Έμ λͺ¨λ μ£Όμ μμΌ ν¨μλ λ°λμ μ€λ₯ μ²΄ν¬ νμ
- μ€λ₯ λ°μ μ, μ½λλ‘λ μμΈλ§ νμΈν μ μμΌλ―λ‘ → μ¬μ©μλ κ°λ°μκ° μ΄ν΄ν μ μλ λ©μμ§λ‘ μΆλ ₯ νμ
β μμΌ ν¨μ μ€λ₯ μ²λ¦¬ μ ν (3κ°μ§)
μ ν λ²νΈ μ€λͺ μμ
β μ€λ₯ μ²λ¦¬ νμ μμ | 리ν΄κ°μ΄ μκ±°λ μ€ν¨ κ°λ₯μ± μμ | closesocket() λ± μΌλΆ ν¨μ |
①리ν΄κ° μμ²΄κ° μ€λ₯ μ 보 ν¬ν¨ | μ€ν¨ μ 0 λλ μμ λ±μΌλ‘ λ¦¬ν΄ | WSAStartup() |
⒠리ν΄κ°κ³Ό μ€λ₯ μ½λ λΆλ¦¬ | μ€ν¨ νμΈ ν μ€λ₯ μ½λ ν¨μ νΈμΆ | λλΆλΆμ μμΌ ν¨μ (socket(), bind() λ±) |
μ£Όλ‘ μ¬μ©νλ λ°©μμ β’λ², μ¦ "리ν΄κ° νμΈ ν → μ€λ₯ μ½λ ν¨μ νΈμΆ"μ΄λ€.
β 1. μλμ° μμΌ μ€λ₯ μ²λ¦¬ λ°©μ
π λν ν¨μ: WSAGetLastError()
- λλΆλΆμ μμΌ ν¨μλ μ€ν¨ μ INVALID_SOCKET, SOCKET_ERROR λ±μ κ°μ 리ν΄
- ꡬ체μ μΈ μ€λ₯λ **WSAGetLastError()**λ₯Ό ν΅ν΄ νμΈ
cpp
볡μ¬νΈμ§
#include <winsock2.h>
#include <stdio.h>
#pragma comment(lib, "ws2_32")
int main() {
WSADATA wsa;
int result = WSAStartup(MAKEWORD(2, 2), &wsa);
if (result != 0) {
printf("WSAStartup μ€ν¨: μ½λ %d\\n", result);
return 1;
}
SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET) {
int errCode = WSAGetLastError();
printf("μμΌ μμ± μ€ν¨: μ½λ %d\\n", errCode);
}
WSACleanup();
return 0;
}
π μ€λ₯ λ©μμ§ μΆλ ₯ ν¨μ (μ ν μ μ©)
μλμ°μμλ μ€λ₯ μ½λμ λ°λ₯Έ μμ€ν λ©μμ§λ₯Ό μΆλ ₯νλ €λ©΄ **FormatMessage()**λ₯Ό μ¬μ©ν μ μμ:
cpp
볡μ¬νΈμ§
#include <windows.h>
void print_error_message(DWORD errCode) {
LPVOID msg;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL, errCode, 0, (LPTSTR)&msg, 0, NULL);
printf("μ€λ₯ λ©μμ§: %s\\n", (char*)msg);
LocalFree(msg);
}
β μμ½ νλ¦
plaintext
볡μ¬νΈμ§
[μμΌ ν¨μ νΈμΆ]
↓
[리ν΄κ°μΌλ‘ μ€ν¨ μ¬λΆ νμΈ]
↓
[WSAGetLastError() νΈμΆ]
↓
[μ€λ₯ μ½λ μΆλ ₯ λλ λ©μμ§ λ³ν]
π μ€λ₯ μ½λ μμ
μ½λ μλ―Έ
10013 | κΆν μμ (Access denied) |
10048 | μ£Όμ μ΄λ―Έ μ¬μ© μ€ (Address already in use) |
10061 | λμ μ°κ²° κ±°λΆ (Connection refused) |
10060 | μ°κ²° μκ° μ΄κ³Ό (Connection timed out) |
μ 체 μ½λ λͺ©λ‘μ MSDNμ΄λ WinError.hμμ νμΈ κ°λ₯
μλλ Chapter 02μ μ£Όμ λ΄μ©μ κ°κ²°νκ² μ 리ν μμ½λ³Έμ΄λ€. ν΅μ¬ ν¨μμ κ°λ μ νλ«νΌ λ³ μ°¨μ΄μ ν¨κ» ꡬ쑰μ μΌλ‘ μ 리ν΄λμμΌλ, μμΌ νλ‘κ·Έλλ°μ μ΄κΈ° λ¨κ³μμ μ€μ μ μ©μ μν λΉ λ₯Έ μ°Έμ‘°μ©μΌλ‘ νμ©νκΈ° μ’λ€.
β Chapter 02 μμ½: μμΌ μμνκΈ°
β 01. μ€λ₯ μ²λ¦¬
νλͺ© Windows Linux / POSIX
μ€λ₯ μ½λ μ»κΈ° | WSAGetLastError() | μ μ λ³μ errno |
μ€λ₯ λ©μμ§ μ»κΈ° | FormatMessage() | strerror(errno) λλ perror() |
λͺ¨λ μ£Όμ μμΌ ν¨μ (socket(), bind(), connect() λ±)λ μ€ν¨ μ μ€λ₯ μ½λ λ°ν νμ
β 02. μμ μ΄κΈ°νμ μ’ λ£ (Windows νμ )
ν¨μ μ€λͺ
WSAStartup() | μμΌ μ¬μ©μ μν λΌμ΄λΈλ¬λ¦¬ μ΄κΈ°ν (Winsock 2.x μ¬μ©) |
WSACleanup() | μμΌ μ¬μ© μ’ λ£, 리μμ€ λ°ν |
β WSAStartup()μ λ°λμ closesocket() ν WSACleanup()μΌλ‘ μ 리ν΄μΌ ν¨
β 03. μμΌ μμ±
ν¨μ μ€λͺ
socket() | ν΅μ μ© μμΌ μμ±, λ΄λΆ 리μμ€λ₯Ό ν λΉνκ³ νΈλ€(SOCKET) λ¦¬ν΄ |
π TCP/UDP μ€μ μ‘°ν© μμ
νλ‘ν μ½ μ£Όμ μ²΄κ³ (af) μμΌ νμ (type) νλ‘ν μ½ (protocol)
TCP | AF_INET, AF_INET6 | SOCK_STREAM | 0 |
UDP | AF_INET, AF_INET6 | SOCK_DGRAM | 0 |
protocol = 0μ΄λ©΄ typeμ λ°λΌ μλ μ§μ (TCP: IPPROTO_TCP, UDP: IPPROTO_UDP)
β 04. μμΌ λ«κΈ°
νλ«νΌ ν¨μ λͺ μ€λͺ
Windows | closesocket() | μμΌ μ’ λ£ λ° λ¦¬μμ€ ν΄μ |
Linux/Unix | close() | νμΌ λμ€ν¬λ¦½ν° λ°©μ μμΌ μ’ λ£ |
β μ€λ¬΄ μμ½ νλ¦ (Windows κΈ°μ€)
plaintext
볡μ¬νΈμ§
[WSAStartup()] → [socket()] → [μ¬μ©] → [closesocket()] → [WSACleanup()]
Linuxλ WSAStartup() / WSACleanup() κ³Όμ μμ΄ λ°λ‘ socket() ~ close() μ¬μ©
π μΆκ° μμ½ λ©λͺ¨
- socket() 리ν΄κ°μ μ€ν¨ μ INVALID_SOCKET (Windows) / 1 (Linux)
- 리ν΄κ° νμΈ ν μ¦μ μ€λ₯ μ½λ μΆμ νλ μ΅κ΄ μ€μ
- λͺ¨λ 리μμ€λ μ¬μ© ν λ°λμ ν΄μ (closesocket() λλ close())
μ’μ, μλλ μ°μ΅λ¬Έμ 01~05-AκΉμ§μ λν μꡬμ¬ν ν΄μ → μ½λ μμ → κ²°κ³Ό ν΄μ€ νλ¦μΌλ‘ μ 리ν μμ±λ λμ ν΄μ€μ΄λ€. Windows νκ²½μμμ Winsock νλ‘κ·Έλλ°μ κΈ°μ΄λΆν° μμ©κΉμ§ 체κ³μ μΌλ‘ λ€λ£° μ μλλ‘ μ€κ³νμΌλ©°, InitSocket μμ μμ κ³Ό μ¬μ©μ μ μ ν¨μ μ€λ₯ μ²λ¦¬ λ‘μ§κΉμ§ λͺ¨λ ν¬ν¨νλ€.
β μ°μ΅λ¬Έμ 01: wsa λ³μμ μ£Όμ νλ μΆλ ₯
π§ μꡬ μ¬ν
- WSADATA ꡬ쑰체μ λ€μ 4κ° νλλ₯Ό μΆλ ₯
- wVersion, wHighVersion, szDescription, szSystemStatus
- Winsock 1.1 λ²μ μμ²(MAKEWORD(1,1)) μ κ° λΉκ΅
π μ½λ μμ
cpp
볡μ¬νΈμ§
#include <winsock2.h>
#include <stdio.h>
#pragma comment(lib, "ws2_32")
int main() {
WSADATA wsa;
int result = WSAStartup(MAKEWORD(1, 1), &wsa);
if (result != 0) {
printf("WSAStartup μ€ν¨: %d\\n", result);
return 1;
}
printf("wVersion: %x\\n", wsa.wVersion);
printf("wHighVersion: %x\\n", wsa.wHighVersion);
printf("szDescription: %s\\n", wsa.szDescription);
printf("szSystemStatus: %s\\n", wsa.szSystemStatus);
WSACleanup();
return 0;
}
π‘ κ²°κ³Ό μμ (λ²μ 1.1 μμ² μ)
plaintext
볡μ¬νΈμ§
wVersion: 101
wHighVersion: 202
szDescription: WinSock 2.0
szSystemStatus: Running
β wVersionμ μμ²λ λ²μ , wHighVersionμ μ§μ κ°λ₯ν μ΅λ λ²μ
β μ°μ΅λ¬Έμ 02-A / 02-B: UDP μμΌ μμ±
π μ½λ μμ (IPv4 κΈ°λ° UDP)
cpp
볡μ¬νΈμ§
SOCKET udp_sock = socket(AF_INET, SOCK_DGRAM, 0);
if (udp_sock == INVALID_SOCKET)
err_quit("UDP μμΌ μμ± μ€ν¨");
β SOCK_DGRAM, protocol = 0 → UDP
β μ°μ΅λ¬Έμ 03-A / 03-B: IPv6 κΈ°λ° TCP μμΌ μμ±
π μ½λ μμ
cpp
볡μ¬νΈμ§
SOCKET tcp6_sock = socket(AF_INET6, SOCK_STREAM, 0);
if (tcp6_sock == INVALID_SOCKET)
err_quit("IPv6 TCP μμΌ μμ± μ€ν¨");
β AF_INET6μΌλ‘ μ£Όμ 체κ³λ₯Ό IPv6λ‘ μ€μ
β μ°μ΅λ¬Έμ 04-A / 04-B: IPv6 κΈ°λ° UDP μμΌ μμ±
π μ½λ μμ
cpp
볡μ¬νΈμ§
SOCKET udp6_sock = socket(AF_INET6, SOCK_DGRAM, 0);
if (udp6_sock == INVALID_SOCKET)
err_quit("IPv6 UDP μμΌ μμ± μ€ν¨");
β μ°μ΅λ¬Έμ 05-A: μ¬μ©μ μ μ ν¨μ μ€λ₯ μ²λ¦¬ (WSASetLastError μ¬μ©)
π§ μꡬ μ¬ν
- μ λ ₯κ°μ΄ μμλ©΄ SOCKET_ERROR λ°ν, **WSASetLastError()**λ‘ μ€λ₯ μ½λ μ§μ
- μ±κ³΅μ΄λ©΄ 0, μ€λ₯μ½λλ 0
π μ½λ μμ
cpp
볡μ¬νΈμ§
#include <winsock2.h>
#include <stdio.h>
#pragma comment(lib, "ws2_32")
void err_quit(const char* msg) {
fprintf(stderr, "[μ€λ₯] %s: %d\\n", msg, WSAGetLastError());
exit(1);
}
int f(int x) {
if (x >= 0) {
WSASetLastError(0);
return 0;
} else {
WSASetLastError(WSAEINVAL); // Invalid argument
return SOCKET_ERROR;
}
}
int main() {
WSAStartup(MAKEWORD(2, 2), &(WSADATA){0});
int retval = f(-100);
if (retval == SOCKET_ERROR)
err_quit("f()");
WSACleanup();
return 0;
}
π‘ μΆλ ₯ μμ
plaintext
볡μ¬νΈμ§
[μ€λ₯] f(): 10022
β 10022λ WSAEINVALμ ν΄λΉνλ μ€λ₯ μ½λ (Invalid argument)
π μ 체 μμ½
λ¬Έμ μ£Όμ ν¬μΈνΈ
01 | WSADATA νλ ν΄μ λ° λ²μ λ³ν κ΄μ°° |
02 | UDP μμΌ μμ±: SOCK_DGRAM, AF_INET |
03 | IPv6 TCP μμΌ μμ±: AF_INET6, SOCK_STREAM |
04 | IPv6 UDP μμΌ μμ±: AF_INET6, SOCK_DGRAM |
05 | μ¬μ©μ μ μ μ€λ₯ μ²λ¦¬ ν¨μ: WSASetLastError() νμ© |
μ’μ, μ¬κΈ°μλ μ€μ΅ 2-2μ ν΅μ¬μΈ μμΌ μμ±κ³Ό λ«κΈ° (μλμ° vs 리λ μ€) λ₯Ό μ€μ΅ νκ²½μ λ§κ² λΆλ¦¬νμ¬ κ΅¬μ±νκ³ , μ€μ μ½λ μ€λͺ κΉμ§ μ 리ν΄μ€κ². λͺ©μ μ μμΌμ λ§λ€κ³ → μ±κ³΅ λ©μμ§λ₯Ό μΆλ ₯νκ³ → λ«λ μΌλ ¨μ κ³Όμ μ ν΅ν΄ μμΌ νλ‘κ·Έλλ°μ κ°μ₯ κΈ°λ³Έ 루ν΄μ 체λνλ κ²μ΄μΌ.
β μ€μ΅ 2-2: μμΌ μμ±κ³Ό λ«κΈ°
π₯οΈ Windows νκ²½: InitSocket.cpp
cpp
볡μ¬νΈμ§
#include "..\\..\\Common.h"
int main(int argc, char* argv[]) {
// 1. μμ μ΄κΈ°ν
WSADATA wsa;
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
return 1;
printf("[μλ¦Ό] μμ μ΄κΈ°ν μ±κ³΅\\n");
// 2. μμΌ μμ± (IPv4, TCP)
SOCKET sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET)
err_quit("socket()");
printf("[μλ¦Ό] μμΌ μμ± μ±κ³΅\\n");
// 3. μμΌ λ«κΈ°
closesocket(sock);
// 4. μμ μ’
λ£
WSACleanup();
return 0;
}
π ν¬μΈνΈ μμ½
λ¨κ³ ν¨μ μ€λͺ
1 | WSAStartup() | Winsock μ΄κΈ°ν (νμ) |
2 | socket() | μμΌ μμ± (IPv4 + TCP) |
3 | closesocket() | μμΌ μμ λ°ν |
4 | WSACleanup() | Winsock μ’ λ£ λ° μ 리 |
err_quit() ν¨μλ Common.hμ μ μλ μ¬μ©μ μ μ μ€λ₯ μΆλ ₯ ν¨μ. WSAGetLastError()λ₯Ό ν¨κ» μΆλ ₯ν¨.
π§ Linux νκ²½: InitSocket.cpp
cpp
볡μ¬νΈμ§
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h> // close()
#include <sys/socket.h> // socket()
#include <netinet/in.h> // AF_INET
int main(int argc, char* argv[]) {
// 1. μμΌ μμ± (IPv4, TCP)
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
perror("socket()");
exit(1);
}
printf("[μλ¦Ό] μμΌ μμ± μ±κ³΅\\n");
// 2. μμΌ λ«κΈ°
close(sock);
return 0;
}
π Linux ν¬μΈνΈ μ°¨μ΄
νλͺ© μλμ° λ¦¬λ μ€
μ΄κΈ°ν | WSAStartup() | νμ μμ |
μ’ λ£ | WSACleanup() | νμ μμ |
μμΌ νμ | SOCKET (typedef) | int |
λ«κΈ° ν¨μ | closesocket() | close() |
μ€λ₯ μ½λ | WSAGetLastError() | errno + perror() |
π μ½μ κ²°κ³Ό μμ
plaintext
볡μ¬νΈμ§
[μλ¦Ό] μμ μ΄κΈ°ν μ±κ³΅
[μλ¦Ό] μμΌ μμ± μ±κ³΅
→ μ±κ³΅ ν μ’
λ£
λλ Linuxμμ:
bash
볡μ¬νΈμ§
$ ./InitSocket
[μλ¦Ό] μμΌ μμ± μ±κ³΅
β μμ½ νλ¦
plaintext
볡μ¬νΈμ§
[μμΌ μμ±]
↓
[μλ¬ νμΈ]
↓
[μ μ λ©μμ§ μΆλ ₯]
↓
[μμ μ 리 (close)]
π μ€μ΅ μ°μ₯ μμ΄λμ΄
- AF_INET6 κΈ°λ°μΌλ‘ μμΌ μμ± μλν΄λ³΄κΈ°
- **SOCK_DGRAM**μΌλ‘ UDP μμΌ μ€μ΅
- μ€ν¨ μ μ€λ₯ μ½λ μΆλ ₯ λ° λ©μμ§ν μ°μ΅
μ΄ μ μμλ μμΌ νλ‘κ·Έλλ°μμμ "μ£Όμ 체κ³(Address Family)"μ "μμΌ νμ (Socket Type)"μ κ°λ κ³Ό μν μ λͺ νν μ€λͺ νκ³ μλ€. μ€λ¬΄μ μΌλ‘λ socket() ν¨μμ 첫 λ²μ§Έμ λ λ²μ§Έ μΈμλ₯Ό μ νν μ΄ν΄νκ³ μ€μ νλ κ²μ΄ κ°μ₯ κΈ°μ΄μ΄μ ν΅μ¬μ΄λ€. μλ λ΄μ©μ μμ½κ³Ό λμ μ€μ¬μΌλ‘ μ¬κ΅¬μ±ν΄ μ€κ².
β μμΌ νλ‘κ·Έλλ°μμμ μ£Όμ 체κ³μ μμΌ νμ
π 1. μ£Όμ μ²΄κ³ (Address Family)
κ°λ :
- ν΅μ λμμ μ£Όμ νμμ μ μ
- μ΄λ€ λ€νΈμν¬ νλ‘ν μ½(IP, Bluetooth λ±)μ μ¬μ©ν μ§λ₯Ό μ νν¨
λν μ£Όμ μ²΄κ³ κ°
μ¬μ© λͺ©μ μμ«κ° μ€λͺ
IPv4 ν΅μ | AF_INET | IPv4 μ£Όμ μ¬μ© (μ: 192.168.0.1) |
IPv6 ν΅μ | AF_INET6 | IPv6 μ£Όμ μ¬μ© (μ: 2001:abcd::1) |
Bluetooth ν΅μ | AF_BTH | λΈλ£¨ν¬μ€ ν΅μ μ© |
Unix Domain Socket | AF_UNIX | λ‘컬 νλ‘μΈμ€ κ° ν΅μ (리λ μ€ μ μ©) |
β socket() ν¨μμ 첫 λ²μ§Έ μΈμλ‘ μ¬μ©λ¨
π 2. μμΌ νμ (Socket Type)
κ°λ :
- λ°μ΄ν° μ μ‘ λ°©μ λ° μ λ’°μ± μ¬λΆλ₯Ό κ²°μ
- TCP/UDP λλ λ€λ₯Έ νλ‘ν μ½μ μ¬μ©ν λμ μ μ‘ νΉμ±μ μ μ
λν μμΌ νμ κ°
μμΌ νμ νΉμ± μ€λͺ
SOCK_STREAM | μ°κ²°ν, μ λ’°μ± λ³΄μ₯ (ex. TCP) |
SOCK_DGRAM | λΉμ°κ²°ν, μ λ’°μ± μμ (ex. UDP) |
β socket() ν¨μμ λ λ²μ§Έ μΈμλ‘ μ¬μ©λ¨
π§ μ’ ν© μ€μ κ°μ΄λ: TCP vs UDP
μ¬μ©ν νλ‘ν μ½ μ£Όμ μ²΄κ³ (af) μμΌ νμ (type)
TCP (IPv4/6) | AF_INET λλ AF_INET6 | SOCK_STREAM |
UDP (IPv4/6) | AF_INET λλ AF_INET6 | SOCK_DGRAM |
νλ‘ν μ½ λ²νΈλ μΌλ°μ μΌλ‘ 0μ μ λ ₯νλ©΄ typeμ λ§μΆ° μλμΌλ‘ μ€μ λ¨
π μ€λ¬΄ λ©λͺ¨: νμ νΈνμ±κ³Ό SOCKET μ μ
- Windows:
- **SOCKET**μ μ μλ μλ£ν (unsigned int λ±) → closesocket() μ¬μ©
- Linux:
- **socket()**μ int νμ μ λ°ν → close() μ¬μ©
- νΈνμ± ν보 λ°©λ²:
- cpp 볡μ¬νΈμ§ // Linuxμμ Windows μ½λμ λμΌνκ² μ¬μ© κ°λ₯νλλ‘ λ§€ν typedef int SOCKET
κ²°λ‘ μμ½
plaintext
볡μ¬νΈμ§
[1λ¨κ³] μ£Όμ μ²΄κ³ μ ν (IPv4 vs IPv6 λ±)
↓
[2λ¨κ³] μμΌ νμ
μ ν (TCP vs UDP λ±)
↓
[3λ¨κ³] socket() νΈμΆ → SOCKET νΈλ€ λ°ν
μ΄ κ΅¬μ‘°κ° λ°λ‘ λͺ¨λ λ€νΈμν¬ νλ‘κ·Έλ¨μ μμμ μ΄ λλ μμΌ μμ± κΈ°λ³Έ 곡μμ΄μΌ.
μ΄λ² μ μ socket() ν¨μμ μΈ λ²μ§Έ μΈμμΈ νλ‘ν μ½ μ§μ λ°©λ², κ·Έλ¦¬κ³ μμΌμ μ’ λ£ν λ μ¬μ©νλ closesocket() vs close() ν¨μμ λν μ 리λ₯Ό λ€λ£¨κ³ μμ΄. μ€λ¬΄μμλ λΉλ²νκ² λ°μνλ νΌμ© μΌμ΄μ€(AF vs PF), 리μμ€ λμ λ°©μ§ κ΄λ ¨ν΄μλ μ€μν κ°λ μ΄λ, μ€μ΅ κ΄μ μΌλ‘ μ¬μ 리ν΄μ€κ².
β μμΌ μμ± μ νλ‘ν μ½ μ€μ + μμΌ λ«κΈ°
π 1. socket() ν¨μμ μΈ λ²μ§Έ μΈμ: νλ‘ν μ½ (Protocol)
π§ μν
- λμΌν μ£Όμ 체κ³(AF_)μ μμΌ νμ (SOCK_) μ‘°ν©μμ λͺ νν νλ‘ν μ½ μ νμ΄ νμν λ μ¬μ©
μμ: socket() ν¨μ μκ·Έλμ²
c
볡μ¬νΈμ§
int socket(int domain, int type, int protocol);
[ν 2-4] TCPμ UDP μ€μ
μ¬μ©ν νλ‘ν μ½ μ£Όμ μ²΄κ³ (domain) μμΌ νμ (type) νλ‘ν μ½ (protocol)
TCP | AF_INET, AF_INET6 | SOCK_STREAM | IPPROTO_TCP (or 0) |
UDP | AF_INET, AF_INET6 | SOCK_DGRAM | IPPROTO_UDP (or 0) |
β οΈ μ€λ¬΄μμλ protocol μ리μ λ³΄ν΅ 0μ λ£μΌλ©΄, typeμ λ°λΌ TCP/UDPκ° μλμΌλ‘ κ²°μ λ¨
π νλ‘ν μ½ κ° μμ μμ½
μ΄λ¦ κ° (보ν΅) μ€λͺ
IPPROTO_TCP | 6 | TCP νλ‘ν μ½ |
IPPROTO_UDP | 17 | UDP νλ‘ν μ½ |
0 | μλ μ§μ | type κ° κΈ°μ€ μλ μ€μ |
π 2. AF_INET vs PF_INET
μ€μ΅ μ€ ν·κ°λ¦΄ μ μλ κ°λ , νμ€ν μ 리ν΄λ³΄μ.
κ΅¬λΆ μλ―Έ μ€μ κ° λμΌ μ¬μ© μμΉ (κ³Όκ±° κΈ°μ€)
AF_INET | Address Family (μ£Όμ 체κ³) | β κ°μ | μμΌ μ£Όμ ꡬ쑰체 μ¬μ© (μ: struct sockaddr_in) |
PF_INET | Protocol Family (νλ‘ν μ½ κ³μ΄) | β κ°μ | socket() ν¨μμμ μ¬μ© |
β μ§κΈμ λλΆλΆμ λ¬Έμμ μ½λμμ AF_ κ³μ΄λ‘ ν΅μΌνμ¬ μ¬μ©
π 3. μμΌ λ«κΈ° (closesocket() vs close())
β Windows
c
볡μ¬νΈμ§
#include <winsock2.h>
int closesocket(SOCKET s); // 리ν΄κ°: μ±κ³΅ 0, μ€ν¨ SOCKET_ERROR
β Linux
c
볡μ¬νΈμ§
#include <unistd.h>
int close(int fd); // 리ν΄κ°: μ±κ³΅ 0, μ€ν¨ -1
π μ£Όμν μ
νλͺ© Windows Linux
μμΌ νμ | SOCKET | int (νμΌ λμ€ν¬λ¦½ν°) |
λ«κΈ° ν¨μ | closesocket() | close() |
μ€λ₯ νμΈ | WSAGetLastError() | errno / perror() |
β οΈ close()λ‘ Winsock μμΌμ μ’ λ£νλ©΄ 리μμ€ ν΄μ κ° λΆμμ ν΄μ§ μ μμ → Windowsμμλ closesocket() νμ
π§ μ’ ν© νλ¦: μμΌ μμ± ~ μ’ λ£
c
볡μ¬νΈμ§
// 1. μμΌ μμ± (TCP μμ)
SOCKET sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); // or 0
// 2. ν΅μ μμ
// 3. μμΌ μ’
λ£
closesocket(sock); // Windows
close(sock); // Linux
π μ 리 λ©λͺ¨
κ°λ ν€μλ μ€λͺ
μ£Όμ μ²΄κ³ | AF_INET, AF_INET6 | IPv4/IPv6μ© μ£Όμ μ§μ |
μμΌ νμ | SOCK_STREAM, SOCK_DGRAM | TCP/UDP μ μ‘ μ ν |
νλ‘ν μ½ | IPPROTO_TCP, IPPROTO_UDP, 0 | λͺ μ λλ μλ μ§μ |
μμΌ μ’ λ£ | closesocket() vs close() | νλ«νΌλ³ μ’ λ£ λ°©μ |
AF vs PF | μ€μ§μ μ°¨μ΄ μμ | AF_INET μ¬μ© κΆμ₯ |
μ΄λ² μ μ μμΌ νλ‘κ·Έλλ°μ κ°μ₯ κΈ°λ³Έμ΄ λλ socket() ν¨μ νΈμΆ λ°©μ, μ¦ μμΌμ μμ±κ³Ό κ°λ μ μ§μ€νκ³ μμ΄. Windowsμ Linux κ°μ μ°¨μ΄μ , κ·Έλ¦¬κ³ socket() ν¨μ νΈμΆ μ μ λ¬ν΄μΌ νλ μΈ κ°μ§ ν΅μ¬ μΈμ — μ£Όμ 체κ³, μμΌ νμ , νλ‘ν μ½ — μ λν΄ μμ£Ό μ€μνκ³ λ μ€μ©μ μΈ λ΄μ©μ λ€λ£¨κ³ μμ΄.
μλμ ꡬ쑰νν΄μ ν΅μ¬ μμ½κ³Ό μ€μ΅ν μ½λκΉμ§ μ 리ν΄μ€κ².
β Chapter 03: μμΌ μμ±κ³Ό λ«κΈ° – ν΅μ¬ μμ½
π 1. μμΌ μμ±μ΄λ?
- socket() ν¨μλ λ€νΈμν¬ ν΅μ μ μν νΈλ€(=μμΌ λμ€ν¬λ¦½ν°) μ μμ±
- μ΄ νΈλ€μ λ€νΈμν¬ μμμ λν μ κ·Ό κΆνμ μλ―Έ
- μμ±λ μμΌ λμ€ν¬λ¦½ν°λ μ΄ν bind(), connect(), send(), recv() λ±μ ν¨μμ μ λ¬
π§© socket() ν¨μ νλ‘ν νμ λΉκ΅
OS ν¨μ μ μ μ€λͺ
Windows | SOCKET socket(int af, int type, int protocol); | **SOCKET**μ λ³λ μ μλ νμ |
Linux | int socket(int domain, int type, int protocol); | **int**ν νμΌ λμ€ν¬λ¦½ν° |
β λ°νκ°μ λ λ€ μμΌ νΈλ€κ°, μ€ν¨ μ INVALID_SOCKET (Windows) λλ -1 (Linux)
π§ socket() ν¨μμ μΈ κ°μ§ μΈμ
μΈμ μ΄λ¦ μ€λͺ λ° μμ κ°
1 | μ£Όμ μ²΄κ³ | AF_INET, AF_INET6 (IPv4/6), AF_BLUETOOTH, AF_UNIX |
2 | μμΌ νμ | SOCK_STREAM (TCP), SOCK_DGRAM (UDP) |
3 | νλ‘ν μ½ |
π» μμ μ½λ – Windows (TCP μμΌ μμ±)
cpp
볡μ¬νΈμ§
#include <winsock2.h>
#include <stdio.h>
#pragma comment(lib, "ws2_32")
int main() {
WSADATA wsa;
if (WSAStartup(MAKEWORD(2, 2), &wsa) != 0)
return 1;
SOCKET sock = socket(AF_INET, SOCK_STREAM, 0); // TCP
if (sock == INVALID_SOCKET) {
printf("μμΌ μμ± μ€ν¨\\n");
WSACleanup();
return 1;
}
printf("μμΌ μμ± μ±κ³΅: %d\\n", (int)sock);
closesocket(sock);
WSACleanup();
return 0;
}
π§ μμ μ½λ – Linux (UDP μμΌ μμ±)
c
볡μ¬νΈμ§
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main() {
int sock = socket(AF_INET, SOCK_DGRAM, 0); // UDP
if (sock < 0) {
perror("μμΌ μμ± μ€ν¨");
exit(1);
}
printf("μμΌ μμ± μ±κ³΅: %d\\n", sock);
close(sock);
return 0;
}
π μ 리: μμΌ μμ± ν΅μ¬ ν¬μΈνΈ
νλͺ© λ΄μ©
νλ«νΌ μ°¨μ΄ | Windows: WSAStartup() νμ / 리λ μ€λ μμ |
리ν΄κ° | μ€ν¨ μ Windows: INVALID_SOCKET, Linux: -1 |
ν΄λ‘μ§ | Windows: closesocket() / Linux: close() |
μΌλ° μ€μ | TCP: AF_INET, SOCK_STREAM, 0 / UDP: AF_INET, SOCK_DGRAM, 0 |