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();
}