๋คํธ์ํฌ ํ๋ก๊ทธ๋๋ฐ์ด๋?
๋ฉ๋ฆฌ ๋จ์ด์ ธ ์๋ ํธ์คํธ๋ค์ด ์๋ก ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ์ ์ ์๋๋ก ํ๋ก๊ทธ๋จ์ ๊ตฌํํ๋ ๊ฒ์ด๋ค.
ํ์ผ๊ณผ ๋ฌ๋ฆฌ ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ์ ๋์์ด ๋ฉ๋ฆฌ ๋จ์ด์ ธ ์๊ธฐ ๋๋ฌธ์
์ํํธ์จ์ด ์ฐจ์์์ ํธ์คํธ๋ค๊ฐ์ ์ฐ๊ฒฐ์ ํด์ฃผ๋ ์ฅ์น๊ฐ ํ์ํ ๋ฟ์ด๋ค.
์ด๋ฌํ ๊ธฐ๋ฅ์ ํด์ฃผ๋ ์ฅ์น๋ฅผ ์์ผ(Socket)์ด๋ผ ํ๋ค. ๊ทธ๋์ ์ผ๋ฐ์ ์ผ๋ก ์์ผ ํ๋ก๊ทธ๋๋ฐ์ด๋ผ๋ ์ฉ์ด์ ๋คํธ์ํฌ ํ๋ก๊ทธ๋๋ฐ์ด๋ผ๋ ์ฉ์ด๋ ๊ฐ์ ์๋ฏธ๋ก ์ฌ์ฉ ๋๊ณ ์๋ค.
์์ผ์ด๋ ๋ฉ๋ฆฌ ๋จ์ด์ ธ ์๋ ๋๊ฐ์ ํธ์คํธ(host) ๋ฅผ ์ฐ๊ฒฐ์์ผ์ฃผ๋ ๋งค๊ฐ์ฒด ์ญํ ์ ํ๋ค.
ํ๋กํ ์ฝ์ ์ ์
๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ๋ ๋ฐฉ๋ฒ์ ์ด๋ค ๋ฐฉ๋ฒ์ ์ฐ๋ ๊ฐ์, ๊ทธ ๋ฐฉ๋ฒ๋งํผ์ ์ํธ๊ฐ์ ๋ฐ๋์ ์ผ์น ํด์ผ ํ๋ค.
ํ์ฌ๋์ ์ ํ๋ฅผ ์ฌ์ฉํ๊ณ ํ์ฌ๋์ ํธ์ง๋ฅผ ์ฌ์ฉํ ์๋ ์๋๊ฒ์ฒ๋ผ
์๋ก๊ฐ์ ๊ท์ฝ์ด ํ์ํ๋ค ์ฆ ํ๋กํ ์ฝ์ด๋ '์ปดํจํฐ ์ํธ๊ฐ์ ๋ํ์ ํ์ํ ํต์ ๊ท์ฝ'
์๋์ฐ ๊ธฐ๋ฐ ์์ ๋ฅผ ์ฐธ๊ณ ํ๋ฉฐ ๊ณต๋ถํด๋ณด์.
tcp/ip server
#include <iostream>
#include <stdlib.h>
#include <winsock2.h>
#include <WS2tcpip.h>
#pragma comment(lib, "ws2_32.lib")
void ErrorHandling(const char* message);
int main(int argc, char* argv[])
{
WSADATA wsaData;
SOCKET hServSock, hClntSock;
SOCKADDR_IN servAddr, clntAddr;
int szClntAddr;
char message[] = "Hello World!";
if (argc != 2)
{
printf("Usage : %s <port>\n", argv[0]);
exit(1);
}
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
ErrorHandling("WSAStartup() error!");
hServSock = socket(PF_INET, SOCK_STREAM, 0);
if (hServSock == INVALID_SOCKET)
ErrorHandling("socket() error");
memset(&servAddr, 0, sizeof(servAddr));
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = htonl(INADDR_ANY);
servAddr.sin_port = htons(atoi(argv[1]));
if (bind(hServSock, (SOCKADDR*)&servAddr, sizeof(servAddr)) == SOCKET_ERROR)
ErrorHandling("bind() error");
if (listen(hServSock, 5) == SOCKET_ERROR)
ErrorHandling("listen() error");
szClntAddr = sizeof(clntAddr);
hClntSock = accept(hServSock, (SOCKADDR*)&clntAddr, &szClntAddr);
if (hClntSock == INVALID_SOCKET)
ErrorHandling("accept() error");
send(hClntSock, message, sizeof(message), 0);
closesocket(hClntSock);
closesocket(hServSock);
WSACleanup();
return 0;
}
void ErrorHandling(const char* message)
{
fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}
tcp/ip client
//#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <iostream>
#include <stdlib.h>
#include <winsock2.h>
#include <WS2tcpip.h>
#pragma comment(lib, "ws2_32.lib")
void ErrorHandling(const char* message);
int main(int argc, char* argv[])
{
WSADATA wsaData;
SOCKET hSocket;
SOCKADDR_IN servAddr;
char message[30];
int strLen;
if (argc != 3)
{
printf("Usage : %s <IP> <port>\n", argv[0]);
exit(1);
}
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
ErrorHandling("WSAStartup() error!");
hSocket = socket(PF_INET, SOCK_STREAM, 0);
if (hSocket == INVALID_SOCKET)
ErrorHandling("socket() error");
memset(&servAddr, 0, sizeof(servAddr));
servAddr.sin_family = AF_INET;
//servAddr.sin_addr.s_addr = inet_addr(argv[1]);
servAddr.sin_port = htons(atoi(argv[2]));
inet_pton(AF_INET, argv[1], &servAddr.sin_addr.s_addr);
if (connect(hSocket, (SOCKADDR*)&servAddr, sizeof(servAddr)) == SOCKET_ERROR)
ErrorHandling("connect() error!");
strLen = recv(hSocket, message, sizeof(message) - 1, 0);
if (strLen == -1)
ErrorHandling("read() error!");
printf("Message from server: %s \n", message);
closesocket(hSocket);
WSACleanup();
return 0;
}
void ErrorHandling(const char* message)
{
fputs(message, stderr);
fputc('\n', stderr);
exit(1);
}
ํ๋กํ ์ฝ ์ฒด๊ณ (protocol family)
- Protocol ( ํ๋กํ ์ฝ ) ์ด๋ ๋๋ฐ์ด์ค ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ๋ ๋ฐฉ์์ด๋ค. ์ฆ, ๊ฐ ๋๋ฐ์ด์ค ๊ฐ ์๋ก ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ๊ธฐ ์ํด์ ์ ์ํด ๋์ ์ฝ์์ ๋ปํ๋ค. ์ด๋ฌํ ๊ท์ฝ์ ์ ํด ๋์ง ์์ผ๋ฉด ์๋๊ฐ ๋ด๊ฐ ์๋ํ ๊ฒ๊ณผ ๋ค๋ฅด๊ฒ ๋ฐ์ดํฐ๋ฅผ ์ดํดํ ์๋ ์๋ค.
์์ผ ํต์ ์ ํ ๋ ์ฌ์ฉํ๋ ํ๋กํ ์ฝ ๋ถ๋ฅ๊ฐ ๋ช๊ฐ์ง ์๋ค. ์ด๋ฌํ ๋ถ๋ฅ๋ฅผ ํ๋กํ ์ฝ ์ฒด๊ณ๋ผ๊ณ ํ๋ค.
์ด๋ฌํ ๋ถ๋ฅ๋ฅผ ํ๋กํ ์ฝ ์ฒด๊ณ๋ผ๊ณ ํ๋ฉฐ c ์ธ์ด์์ socket์ ์์ฑํ ๋ ๋ค์๊ณผ ๊ฐ์ด ํจ์๋ฅผ ํธ์ถ ํ ๋ ์ฒซ๋ฒ์งธ ์ธ์์ ํ๋กํ ์ฝ ์ฒด๊ณ๋ฅผ ๋ฃ๋๋ค.
// C code
#include <sys/socket.h>
int socket(PF_INET, int type, int protocol );
์ด๋ฆ | Protocol Family ( ํ๋กํ ์ฝ ์ฒด๊ณ ) |
PF_INET | IPv4 ์ธํฐ๋ท ํ๋กํ ์ฝ ์ฒด๊ณ |
PF_INET6 | IPv6 ์ธํฐ๋ท ํ๋กํ ์ฝ ์ฒด๊ณ |
PF_LOCAL | ๋ก์ปฌ ํต์ ์ ์ํ UNIX ํ๋กํ ์ฝ ์ฒด๊ณ |
PF_PACKET | Low Level ์์ผ์ ์ํ ํ๋กํ ์ฝ ์ฒด๊ณ |
PF_IPX | IPX ๋ ธ๋ฒจ ํ๋กํ ์ฝ ์ฒด๊ณ |
์์ผ ํ์ ( TCP, UDP )
- socket type์ ๋ฐ์ดํฐ ์ ์ก ๋ฐฉ์์ ์๋ฏธ ํ๋ฉฐ socket ํจ์ ํธ์ถ ์ 2๋ฒ์งธ ์ธ์์ ๊ฐ์ ๋ฃ๋๋ค.
// C code
#include <sys/socket.h>
int socket(int domain, SOCK_DGRAM, int protocol);
# Python code
serverSocket = socket(AF_IENT, SOCK_STREAM)
TCP | UDP |
์ฐ๊ฒฐ ์งํฅํ ์์ผ ( 3-way handshake ) | ๋น ์ฐ๊ฒฐ ์งํฅํ ์์ผ |
SOCK_STREAM | SOCK_DGRAM |
๋ฐ์ดํฐ ์์ค ์์ด ๋ชฉ์ ์ง๋ก ์ ์ก | ๋ฐ์ดํฐ ์์ค์ ์ฐ๋ ค๊ฐ ์์ |
์ ์ก ์์๋๋ก ๋ฐ์ดํฐ๊ฐ ์์ | ์ ์ก๋ ์์์ ์๊ด์์ด ๊ฐ์ฅ ๋น ๋ฅธ ์ ์ก์ ์งํฅ |
๋ฐ์ดํฐ ๊ฒฝ๊ณ๊ฐ ์์ | ๋ฐ์ดํฐ ๊ฒฝ๊ณ ์์ |
IP์ฃผ์๋?
์ธํฐ๋ท์์ ์กด์ฌํ๋ ํธ์คํธ๋ค์ ๊ตฌ๋ถํ๊ธฐ ์ํ 32๋นํธ ์ฃผ์ ์ณฌ๊ณ๋ฅผ ์๋ฏธํ๋ค.
๋คํธ์ํฌ ์ฃผ์๋?
๋คํธ์ํฌ๋ฅผ ๊ตฌ๋ถํ์ฌ ์ฃผ๋ ID๋ฅผ ์๋ฏธํ๋ค.
์๋ฅผ ๋ค์ด์ B.COM์ด๋ผ๋ ํ์ฌ์ ๋ฌด ๋๋ฆฌ์๊ฒ ์ ์กํ๋ค๊ณ ๊ฐ์ ํด๋ณด์. ์ด ํ์ฌ๋ ํ๋์ ๋ก์ปฌ ๋คํธ์ํฌ๋ก ์ด๋ฃจ์ด์ ธ ์๋ค. ์ด๋ฌํ ํ์ฌ์ ๋ฌด ๋๋ฆฌ๊ฐ ์ฌ์ฉํ๊ณ ์๋ ์ปดํจํฐ์ ๋ฐ์ดํฐ๋ฅผ ์ ์กํ๊ธฐ ์ํด์, ์ผ๋จ์ B.COM์ ๋คํธ์ํฌ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ์กํด ์ฃผ๋ ๊ฒ์ด ์ฐ์ ์ด๋ค. ์ฆ ์ฒ์๋ถํฐ IP์ฃผ์ 4๋ฐ์ดํธ ๋ชจ๋๋ฅผ ์ฐธ์กฐํด์ ๋ฌด ๋๋ฆฌ์ ์ปดํจํฐ๋ก ๋ฐ๋ก ์ฐพ์๊ฐ๋ ๊ฒ์ด ์๋๋ผ, 4๋ฐ์ดํธ IP์ฃผ์์ค์์ ๋คํธ์ํฌ ์ฃผ์๋ง์ ์ฐธ์กฐํด์ ์ผ๋จ B.COM์ ๋คํธ์ํฌ๋ฅผ ๋จผ์ ์ฐพ์๊ฐ๋ค.
Port๋ ๋ฌด์์ธ๊ฐ?
์ผ๋ฐ์ ์ผ๋ก ํ๋์ ์ปดํจํฐ ์์์ ์ฌ๋ฌ๊ฐ์ ์ดํ๋ฆฌ์ผ์ด์ ์ด ๋์์ ๋คํธ์ํฌ๋ฅผ ํตํด์ ๋ค๋ฅธ ์ปดํจํฐ์ ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ ๋ฐ๋๋ค. ๊ฐ์ธ์ด ์ฌ์ฉํ๋ IP๋ ํ๋์ ๋ฌผ๋ฆฌ์ ์ธ ์ฅ์น (๋คํธ์ํฌ ์นด๋)๋ฅผ ํตํด์ ๋คํธ์ํฌ์ ์ฐ๊ฒฐ๋์ด ์๋ค. IP์ฃผ์๋ก๋ ์ธํฐ๋ท์ด ์ฐ๊ฒฐ๋์ด์๋ ์ปดํจํฐ๋ฅผ ๊ตฌ๋ถํ์ฌ ์ค ์๋ ์์ด๋ ์ปดํจํฐ์์์ ์คํ๋๊ณ ์๋ ํ๋ก๊ทธ๋จ๊น์ง ๊ตฌ๋ถํ์ฌ ์ฃผ์ง๋ ๋ชปํ๋ค.
์ด๊ฒ์ ๊ตฌ๋ถ์์ผ์ฃผ๋ ๊ฒ์ด ๋ฐ๋ก PORT ๋ค. port๋ 2๋ฐ์ดํธ๋ก ํํ๋๋ฏ๋ก ๊ฐ์ง ์ ์๋ ๊ฐ์ ๋ฒ์๊ฐ 0 ~ 65535 ๊น์ง๋ค.
TCP์์ผ๊ณผ UDP ์์ผ์ port๋ฅผ ์๋ก ๊ณต์ ํ์ง ์์ผ๋ฏ๋ก ์ค๋ณต๋์ด๋ ์๊ด์๋ค.
์ฃผ์ ์ ๋ณด์ ํํ
Ipv4 (32 bit) Ipv6 (128 bit) ์ฃผ์ ์ฒด๊ณ๋ฅผ ์ฌ์ฉํ๋ค.
typedef struct sockaddr_in
{
#if(_WIN32_WINNT < 0x0600)
short sin_family; //์ฃผ์ ์ฒด๊ณ(address faimily)
#else //(_WIN32_WINNT < 0x0600)
ADDRESS_FAMILY sin_family;
#endif //(_WIN32_WINNT < 0x0600)
USHORT sin_port; //16bit tcp/udp port
IN_ADDR sin_addr; //32bit ipv4 ์ฃผ์
CHAR sin_zero[8]; //์ฌ์ฉ๋์ง ์์
} SOCKADDR_IN, *PSOCKADDR_IN;
#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP | WINAPI_PARTITION_SYSTEM | WINAPI_PARTITION_GAMES) */
#pragma endregion
typedef struct in_addr // 32bit ipv4 ์ฃผ์
{
union
{
struct { UCHAR s_b1,s_b2,s_b3,s_b4; } S_un_b;
struct { USHORT s_w1,s_w2; } S_un_w;
ULONG S_addr;
} S_un;
#define s_addr S_un.S_addr /* can be used for most tcp & ip code */
#define s_host S_un.S_un_b.s_b2 // host on imp
#define s_net S_un.S_un_b.s_b1 // network
#define s_imp S_un.S_un_w.s_w2 // imp
#define s_impno S_un.S_un_b.s_b4 // imp #
#define s_lh S_un.S_un_b.s_b3 // logical host
} IN_ADDR, *PIN_ADDR, FAR *LPIN_ADDR;
๋คํธ์ํฌ ๋ฐ์ดํธ ์์
sockaddr_in ๊ตฌ์กฐ์ฒด ๋ณ์์ ๊ฐ์ ๋์ ํ๋ ๊ฒฝ์ฐ์๋ ๋คํธ์ํฌ ๋ฐ์ดํธ ์์(Network Byte Ordering)๋ก ๊ฐ์ ๋ณ๊ฒฝํ ๋ค์์ ๋์ ํด์ผ ํ๋ค. ๊ทธ๋ ๋ค๋ฉด ๋คํธ์ํฌ ๋ฐ์ดํธ ์์๋ผ๋ ๊ฒ์ ๋ฌด์์ ์๋ฏธํ๋๊ฐ?
๋ฐ์ดํธ ์์๋ผ๋ ๊ฒ์ ์์คํ ์ด ๋ด๋ถ์ ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ํํํ๋ ๋ฐฉ๋ฒ์ ์๋ฏธํ๋ค.
ํฌ๊ฒ๋ 2๊ฐ์ง ๋ฐฉ๋ฒ์ผ๋ก ๋๋๋๋ฐ Big-Edian, Little-Edian ๋ฐฉ์์ด๋ค.
์์คํ ๋ด๋ถ์ ์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๋๋ฐ ์์ด์ Big-Edian ๋ฐฉ์์ ์ฐ๋๋ Little-Edian ๋ฐฉ์์ ์ฐ๋๋๋ CPU์ ๋ฐ๋ผ์ ๋ฌ๋ผ์ง๋ค. ์ด๋ฅผ 'ํธ์คํธ ๋ฐ์ดํธ ์์(host byte order)'๋ผ๊ณ ํ๋๋ฐ ๋ฌธ์ ๋ ํธ์คํธ ๋ฐ์ดํธ ์์๊ฐ ์ผ์ ์น ์๋ค๋ ๊ฒ์ด๋ค.
์ด๋ฌํ ๋ฌธ์ ์ ์ ํด๊ฒฐํ๊ธฐ ์ํด์ ํต์ผ๋ ๋ฐฉ์์ธ '๋คํธ์ํฌ ๋ฐ์ดํธ ์์(network byte order)'์ด๋ค.
ํจ์ ๊ตฌ๋ถ | ์ค๋ช |
uint32_t htonl(uint32_t hostlong) | long ํ ํธ์คํธ ๋ฐ์ดํธ ์์ ๋ฐ์ดํฐ๋ฅผ ๋คํธ์ํฌ ๋ฐ์ดํธ ์์๊ฐ ๊ตฌํจ |
uint16_t htons(uint16_t hostshort) | short ํ ํธ์คํธ ๋ฐ์ดํธ ์์ ๋ฐ์ดํฐ๋ฅผ ๋คํธ์ํฌ ๋ฐ์ดํธ ์์๊ฐ ๊ตฌํจ |
uint32_t ntohl(uint32_t netlong) | long ํ ๋คํธ์ํฌ ๋ฐ์ดํธ ์์ ๋ฐ์ดํฐ๋ฅผ ํธ์คํธ ๋ฐ์ดํธ ์์ ๋ฐ์ดํฐ ๊ฐ ๊ตฌํจ |
uint16_t ntohs(uint16_t netshort) | short ํ ๋คํธ์ํฌ ๋ฐ์ดํธ ์์ ๋ฐ์ดํฐ๋ฅผ ํธ์คํธ ๋ฐ์ดํธ ์์ ๋ฐ์ดํฐ ๊ฐ ๊ตฌํจ |
ntohs() ๋ ๋คํธ์ํฌ ๋ฐ์ดํธ ์์๋ฅผ ํธ์คํธ ๋ฐ์ดํธ ์์๋ก ๋ฐ๊พธ์ด ์ฃผ๋ ํจ์์ด๋ค.
์ฃผ์ ์ ๋ณด ํ ๋นํ๊ธฐ
์์ผ์ ์ฃผ์, ํ๋กํ ์ฝ, ํฌํธ๋ฅผ ํ ๋นํ๋ค.
int bind ( SOCKET s, const struct sockaddr *name, int namelen );
- s : socket()์ผ๋ก ์์ฑ๋ ์์ผ๊ฐ์ฒด
- name : ์์ผ๊ฐ์ฒด์ ๋ถ์ฌํ ์ฃผ์์ ๋ณด๋ฅผ ํฌํจํ ๊ตฌ์กฐ์ฒด
- namelen : name์ ๋ฐ์ดํฐ ๊ธธ์ด. byte(:12)๋จ์
'๐ Development Study > ๐ป Win32API' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
์์ (0) | 2022.08.17 |
---|---|
๋ณ์ ๋ฐ ์ ํ (0) | 2022.08.17 |
ํ๋ก๊ทธ๋จ์ ๊ตฌ์กฐ (0) | 2022.08.17 |
์ปดํ์ผ๋ฌ (0) | 2022.08.17 |
Directx12 ์ด๊ธฐํ (0) | 2022.07.25 |
๋๊ธ