네트워크 기초
서버를 구축하면서 안정성에대해 많은 신경을 써야한다. 그렇기 위해서는 이론이 매우 중요하게될 것이다.
그래서 간단하게 알아보자.
네트워크 패킷을 보내는 것은 우리가 알고 있는 택배 시스템과 매우 비슷하다.
빨간집은 고객
초록집은 경비실
파란집은 택배센터라고 해보자.
관심사는 딱 하나이다. 택배를 보내는 과정이 중요하다.
우리가 1번 아파트 단지에서 2번 아파트 단지로 택배를 보낸다고 하면 이런 시스템을 생각해 볼 수 있다.
일단 1번 아파트 단지의 고객은 경비실에 택배를 보낸다. 그렇다면 경비실에서 같은 아파트 단지로 택배를 보낼경우 배송센터를 거칠 필요 없이 바로 배송해주면 된다. 하지만 이 경우는 2번 아파트 단지로 이동하는 것이기 때문에 배송센터로 보낸다.
그러면 배송센터에서는 2번 아파트 경비실로 택배를 보내고 경비실에서 2번 아파트의 고객에게 전달해주는 시스템이다.
이 것이 네트워크랑 비슷하다.
배송센터는 라우터, 경비실은 스위치, 고객은 우리가 쓰는 PC 등이다.
같은 네트워크상에 있는 경우 스위치 입장에서는 주소를 통해 같은 네트워크안에 있음을 파악하고 처리하게된다.
만약 외부 네트워크로 보낸다고 하면 스위치에서 라우터를 통해서 통신한다.
통신 모델
단순히 택배를 보낼 때, 보내는곳만 알고 있으면 택배가 뿅 하고 이동할 수 있을까?? 그건 아닐것이다.
생각해보면
1. 상품이 필요하다.
2. 배송 정책, 택배를 보내는 정책이 필요하다
3. 최종 주소(삼성 아파트 101호에서 현대 아파트 201호로)
4. 단지 경로, 매번 바뀐다.(다음 목적지, 삼성 아프트 101호에서 경비실로)
5. 택배 운송, 매번 바뀐다.
가 필요할 것이다.
이것을 네트워크로 생각해보자.
1. 어플리케이션
2. 트랜스포트 , 전송 확인 / 오류 해결 (TCP, UDP) TCP는 매우 중요하니 나중에 다시 포스팅할 예정
3. 네트워크, 네트워크 간 경로 설정, IPv4, IPv6, 관련 장치는 라우터가 있다.
4. 데이터 링크, 네트워크 내 경로 설정, 이더넷, PPP, 관련 장치는 스위치가 있다.
5. 피지컬 , 물리적인 신호 처리, 케이블 / 허브
자 이것이 TCP/IP 모델이다.
소켓 프로그래밍 입문
식당에서 손님을 받기위해선 뭘 해야할까? 일단 식당에는 손님이 들어올 수 있는 입구가 필요하다. 그리고 문지기가 필요할 것이다. 문지기에게는 무전기를 쥐어준다.
만약 손님이 입장할때, 문지기는 상황을 보고 손님을 입장 시킨 뒤 무전기를 통해서 알려줄 것이다. 그리고 그 손님이 테이블에 앉아서 기다릴 것이다.
이것은 식당의 입장이었다. 그렇다면 손님의 입장으로 봐보자. 손님은 식당의 위치만 알고있다. 그래서 문지기에게 전화를 걸어 입장이 가능한지 문의를 할 것이다.
손님은 핸드폰만 준비해서 식당 번호로 입장 문의를 한 것이고 대리인을 통해 식당과 대화가 가능했다.
식당은 문지기를 고용하고 문지기를 교육해야하며, 영업을 시작해서 문지기를 통해 안내하는 것이다. 손님 대리인과 손님과 소통을 하는 것이다.
이걸 소켓프로그래밍으로 바꾸면 다음과 같다.
코드를 한번 작업해보자.
서버는 다음과 같다.
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace ServerCore
{
class Program
{
static void Main(string[] args)
{
// DNS(Domain Name System)
string host = Dns.GetHostName();
IPHostEntry ipHost = Dns.GetHostEntry(host);
IPAddress ipAddr = ipHost.AddressList[0];
IPEndPoint endPoint = new IPEndPoint(ipAddr, 7777);
// 문지기가 들고있는 휴대폰
Socket listenSocket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
try
{
// 문지기 교육
listenSocket.Bind(endPoint);
// 영업 시작
// backiog : 최대 대기수
listenSocket.Listen(10);
while (true)
{
Console.WriteLine("Listening...");
// 손님 입장
Socket clientSocket = listenSocket.Accept();
// 받는다.
byte[] recvBuff = new byte[1024];
int recvBytes = clientSocket.Receive(recvBuff);
string recvData = Encoding.UTF8.GetString(recvBuff, 0, recvBytes);
Console.WriteLine($"From Client {recvData}");
// 보낸다.
byte[] sendBuff = Encoding.UTF8.GetBytes("Welcome");
clientSocket.Send(sendBuff);
// 쫓아낸다.
clientSocket.Shutdown(SocketShutdown.Both);
clientSocket.Close();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
}
클라는 다음과 같다.
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
namespace ServerCore
{
class Program
{
static void Main(string[] args)
{
// DNS(Domain Name System)
string host = Dns.GetHostName();
IPHostEntry ipHost = Dns.GetHostEntry(host);
IPAddress ipAddr = ipHost.AddressList[0];
IPEndPoint endPoint = new IPEndPoint(ipAddr, 7777);
// 휴대폰 설정
Socket socket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
try
{
// 문지기한테 입장 문의
socket.Connect(endPoint);
Console.WriteLine($"Conneted to {socket.RemoteEndPoint}");
// 보낸다
byte[] sendBuff = Encoding.UTF8.GetBytes("Hello, World!");
int sendBytes = socket.Send(sendBuff);
// 받는다
byte[] recvBuff = new byte[1024];
int recvBytes = socket.Receive(recvBuff);
string recvData = Encoding.UTF8.GetString(recvBuff, 0, recvBytes);
Console.WriteLine($"From Server {recvData}");
// 나간다.
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
catch(Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
}
'Unity > 온라인 RPG' 카테고리의 다른 글
[게임 서버] 네트워크 프로그래밍 - Connector, TCP? UDP?, Buffer와PacketSession (1) | 2024.01.22 |
---|---|
[게임 서버] 네트워크 프로그래밍 - Listener와 Session (0) | 2024.01.19 |
[게임 서버] 멀티쓰레드 프로그래밍 - Context Switching, Event등 Lock의 다양한 기법 (1) | 2024.01.11 |
[게임 서버] 멀티쓰레드 프로그래밍 - Lock에 대해서 (1) | 2024.01.10 |
[게임 서버] 멀티쓰레드 프로그래밍 - 캐시, 메모리 배리어, Interlocked (1) | 2024.01.09 |