TCP, UDP λ μ νμ μ΄λ©μΌ μ°¨μ΄λΌκ³ λΉμ ν μ μλ€.
TCPλ μ°κ²°ν μλΉμ€, UDPλ λΉμ°κ²°ν μλΉμ€λΌ νλ€.
TCP λ μ°κ²°μ μν΄ ν λΉλλ λ Όλ¦¬μ μΈ κ²½λ‘κ° μλ€.
UDP λ μ°κ²°μ΄λΌλ κ°λ μ΄ μκ³ μ μ‘ μμκ° λ³΄μ₯λμ§ μλλ€.
TCPλ μ λ’°μ±μ μ’μ§λ§ μλκ° (UDPμ λΉν΄ μλμ μΌλ‘)λ리λ€.
- λΆμ€μ΄ μΌμ΄λλ©΄ μ± μμ§κ³ λ€μ μ μ‘νλ€.
- 물건μ μ£Όκ³ λ°μ μν©μ΄ μλλ©΄ μΌλΆλ§ 보λΈλ€. (νλ¦/νΌμ‘μ μ΄βοΈ)
- κ³ λ €ν κ²μ΄ λ§μμ μλκ° λ리λ€.
- λ리λλΌλ λ§μ μ¬λμ 곡ννκ²
UDPλ μ λ’°μ±μ λμμ§λ§ μλκ° λΉ λ₯΄λ€.
- λΆμ€μ λν΄λ μ± μμ΄ μμ΄μ λ€νΈμν¬ νΌμ λ¬Έμ , λλΉκ° μ¬ν΄μ§ μ μλ€
- μΌλ¨ 보λ΄κ³ μκ°νλ€.
- λ¨μν΄μ μλκ° λΉ λ₯΄λ€.
- λΉ λ₯΄κ² νλλͺ
λ°μ΄ν° κ²½κ³ Boundary
TCPλ κ²½κ³μ κ°λ μ΄ μλ€ (μμλ 보μ₯λμ§λ§ κ²½κ³κ° μλ, μ»¨λ² μ΄μ΄ λ²¨νΈ λλ)
UDPλ κ²½κ³μ κ°λ μ΄ μλ€ (μμλ 보μ₯λμ§ μμ§λ§ νλ°° ν¬μ₯μ²λΌ κ²½κ³κ° λ±λ± μλ€)
winsock λΌμ΄λΈλ¬λ¦¬λ₯Ό νμ©νμ¬ λ§€μ° κΈ°λ³Έμ μΈ ννμ TCP μλ²λ₯Ό ꡬνν΄λ³Έλ€. blocking ν¨μλ₯Ό μ¬μ©νμ¬ λ‘컬 루νλ°± μ£Όμλ‘ μμ½ μ±ν μ ν΄λ³΄μ
κ°λ¨νκ² μ 리ν΄λ³΄λ©΄ μ΄λ° ννμ΄λ€
ν΄λΌμ΄μΈνΈ
1) μμΌ μμ± (socket)
2) μλ²μ μ°κ²° μμ² (connect)
3) ν΅μ (send, receive)
μλ²
1) μλ‘μ΄ μμΌ μμ± (socket)
2) μμΌμ μ£Όμ/ν¬νΈ λ²νΈ μ€μ (bind)
3) μμΌ μΌ μν€κΈ° (listen)
4) μλ μ μ (accept)
5) ν΄λΌμ ν΅μ (send, receive)
#include "pch.h"
#include <iostream>
// ν΄λΌ
// 1) μλ‘μ΄ μμΌ μμ±
// 2) μλ²μ μ°κ²° μμ²
// 3) μλ²μ ν΅μ
int main()
{
WSAData wsaData;
if (::WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
return 0;
// ad : Address Family (AF_INET = IPv4, AF_INET6 = IPv6)
// type : TCP(SOCK_STREAM) vs UDP(SOCK_DGRAM)
// protocol : 0
// return : descriptor
SOCKET clientSocket = ::socket(AF_INET, SOCK_STREAM, 0);
if (clientSocket == INVALID_SOCKET)
return 0;
SOCKADDR_IN serverAddr; // IPv4
::memset(&serverAddr, 0, sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
//serverAddr.sin_addr.s_addr = ::inet_addr("127.0.0.1"); << deprecated
::inet_pton(AF_INET, "127.0.0.1", &serverAddr.sin_addr);
serverAddr.sin_port = ::htons(7777); // 80 : HTTP
if (::connect(clientSocket, (SOCKADDR*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR)
return 0;
// ---------------------------
// μ°κ²° μ±κ³΅! μ΄μ λΆν° λ°μ΄ν° μ‘μμ κ°λ₯!
cout << "Connected To Server!" << endl;
while (true)
{
// TODO
char sendBuffer[100] = "Hello! I am Client";
int32 resultCode = ::send(clientSocket, sendBuffer, sizeof(sendBuffer), 0);
if (resultCode == SOCKET_ERROR)
return 0;
char recvBuffer[100];
int32 recvLen = ::recv(clientSocket, recvBuffer, sizeof(recvBuffer), 0);
if (recvLen <= 0)
return 0;
cout << "Echo Data : " << recvBuffer << endl;
this_thread::sleep_for(1s);
}
// --------------------------
::closesocket(clientSocket);
::WSACleanup();
}
#include "pch.h"
#include <iostream>
#include <thread>
#include <vector>
using namespace std;
#include <atomic>
#include <mutex>
#include <windows.h>
#include "TestMain.h"
#include "ThreadManager.h"
// μλ²
// 1) μλ‘μ΄ μμΌ μμ± (socket)
// 2) μμΌμ μ£Όμ/ν¬νΈ λ²νΈ μ€μ (bind)
// 3) λ¦¬μ¨ μμΌ μΌ μν€κΈ° (listen)
// 4) μ μλ ν΄λΌμ λν΄μ μλ‘μ΄ μμΌμ μμ± (accept)
// 5) ν΄λΌμ ν΅μ
int main()
{
WSADATA wsaData;
if (::WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
return 0;
// 1) μμΌ μμ±
// ad : Address Family (AF_INET = IPv4, AF_INET6 = IPv6)
// type : TCP(SOCK_STREAM) vs UDP(SOCK_DGRAM)
// protocol : 0
// return : descriptor
//int32 errorCode = ::WSAGetLastError();
SOCKET listenSocket = ::socket(AF_INET, SOCK_STREAM, 0);
if (listenSocket == 0)
return 0;
// 2) μ£Όμ/ν¬νΈ λ²νΈ μ€μ (bind)
// μ°κ²°ν λͺ©μ μ§λ? (IPμ£Όμ + Port) -> XX μννΈ YY νΈ
SOCKADDR_IN serverAddr; // IPv4
::memset(&serverAddr, 0, sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = ::htonl(INADDR_ANY); // μ무 IPλ
serverAddr.sin_port = ::htons(7777); // 80 : HTTP
// host to network short
// Little-Endian vs Big-Endian
// ex) 0x12345678 4λ°μ΄νΈ μ μ
// low [0x78][0x56][0x34][0x12] high < little
// low [0x12][0x34][0x56][0x78] high < big = network
if (::bind(listenSocket, (SOCKADDR*)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR)
return 0;
// 3) μ
무 κ°μ (listen)
if (::listen(listenSocket, SOMAXCONN) == SOCKET_ERROR)
return 0;
// 4) μλ λ§μ΄ (accept)
while (true)
{
SOCKADDR_IN clientAddr;
::memset(&clientAddr, 0, sizeof(clientAddr));
int32 addrLen = sizeof(clientAddr);
SOCKET clientSocket = ::accept(listenSocket, (SOCKADDR*)&clientAddr, &addrLen);
if (clientSocket == INVALID_SOCKET)
return 0;
// μλ μ
μ₯!
char ip[16];
::inet_ntop(AF_INET, &clientAddr.sin_addr, ip, sizeof(ip));
cout << "Client Connected! IP = " << ip << endl;
// 5) TODO
while (true)
{
char recvBuffer[100];
int32 recvLen = ::recv(clientSocket, recvBuffer, sizeof(recvBuffer), 0);
if (recvLen <= 0)
return 0;
cout << "Recv Data : " << recvBuffer << endl;
cout << "Recv Data Len : " << recvLen << endl;
int32 resultCode = ::send(clientSocket, recvBuffer, recvLen, 0);
if (resultCode == SOCKET_ERROR)
return 0;
}
}
::closesocket(listenSocket);
::WSACleanup();
}