C 유동 ip socket 통신 방법

서버(Server)

IP공유기 하나가지고 여러 개의 PC가 접속할 때 다른 유저로 구분하는 것이다. 

ex) 아이피 터널링, 구글 홀펀칭 - 5G 기능

C, C++에는 유니온이라는 구조체가 있다. 서버에 들어갈 경우 알아야 할 개념이다.

서버를 알기 전에 네트워크 기능을 알고, 데이터 통신도 해보고 이동 동기화 전까지만 해보면 될 것이다.

비동기 논블락킹 서버를 구현만 할 수 있으면 된다.

서버에 몬스터 배치까지만 해보고 동기화는 나중에 하겠다.

서버의 한계가 있기 때문에 스마트폰 6명 정도 동기화만 해도 현업 수준이다.

서버와 클라이언트

클라이언트 서버 모델을 게임에 적용한 것이 온라인 게임이다.

서버

서비스 제공자

클라이언트

서비스 요청자

클라이언트 서버 모델

서비스 요청자인 클라이언트와 서비스 자원의 제공자인 서버 간에 작업을 분리해주는 분산 애플리케이션 구조이자 네트워크 아키텍처를 나타낸다.

아키텍처

컴퓨터를 기능면에서 본 구성 방식 기억장치의 번지 방식, 입출력 장치의 구성 방식 등을 가리킴.

일반 적으로 같은 아키텍처의 컴퓨터에는 소프트웨어의 호환성이 있음.

최적화를 목표로 두고 시스템 구성과 동작원리 그리고 시스템의 구성 환경 등을 설명 및 설계하는 청사진 또는 설계도이다.

//tuhbm.github.io/2019/04/24/architecture/

아키텍처란 무엇인가?

용어정리이 카테고리는 비전공자로서 개발자로써 공부하며, 평소 이해하지 못한 단어를 제방식대로 정리하는 카테고리입니다.제방식대로 풀어 쓴것이므로 오류가 있을 수 있습니다.오류가 있

tuhbm.github.io

네트워크 프로그래밍

TCP/IP, UDP 중심의 프로그래밍이다.

네트워크 모델

네트워크 세부 기능들은 매우 복잡하고 다양하다.

이를 체계적으로 분류한 개념적인 모델이다.

네트워크 대표적인 모델 종류는 OSI 7 Layer와 TCP/IP 모델로 기본적으로 이해하고 있어야 한다.

데이터들은 바로 전송되는 것이 아닌 몇 단계씩 걸쳐서 전송이 된다.

마더보드에 랜카드가 부착되어 있고선 랜선을 타고 데이터가 전달이 된다.

그러면 PC 랜선부터 타고 랜카드를 거쳐서 실제 데이터가 응용 프로그램까지 전달되는 과정을 레이어로 설명한다.

그 과정을 7단계 레이어로 보여준 것이 OSI 7 Layer이다.

ex) PC마다 IP(주소)가 있다.

PC와 PC에 데이터를 전송한다.

PC1에서 "안녕하세요"라고 전송하면

데이터가 RP를 타고 거쳐서 PC2까지 전송이 된다.

OSI 7 Layer (Open System Interconnection)

7개의 Layer로 구성한 네트워크로 각 레이어마다 자신의 고유한 기능이 존재한다.

응용 프로그램 계층(Application Layer)

암호를 푼 데이터가 응용 프로그램에 전달되고 사용자나 응용 프로그램 간의 데이터 교환을 가능하게 하는 계층이다.

ex)카톡에서 카톡으로 전송된다.

HTTP, FTP, 터미널 서비스, 여러 메일 프로그램, 디렉토리 서비스 등을 제공한다.

표현 계층(Pressentation Layer)

데이터를 해석하는 단계로 데이터의 구조를 하나의 통일된 형식으로 표현하고, 데이터의 압축과 암호화 기능을 수행한다. 문자열로 보냈으면 바이트 단위로 전송이 된다.

ex) 어플리케이션에서는 바이트 단위로 전송되는 것이기 때문에 문자열로 해석해야 한다.

그 다음 받은 데이터가 암호화가 되어 있다면 암호를 풀어야 한다.

세션 계층(Session Layer)

두 시스템 간의 통신 중 동기화를 유지하고 데이터 교환을 관리한다.

포트를 찾아간다. 몇 번 포트인지 해당 포트로 데이터가 전달된다.

정보 교환을 효과적으로 할 수 있도록 전송 계층에서 설정된 종단 간의 논리적인 연결에 추가 서비스를 제공한다.

전송 계층(Transform Layer)

IP주소의 이동 경로를 전송한다. 종단 간의 신뢰성 있고, 투명한 데이터 전송을 제공한다.

이를 위해 오류 제어, 통신량 제어, 다중화를 제공하며 응용 프로그램 간 통신을 위해 포트를 사용한다.

네트워크 계층(Network Layer)

데이터는 IP주소를 갖고 있다. 8비트 숫자 4개로 구성된 IP주소 체계로 사용하며, 경로 제어와 통신량 제어 등을 수행한다.

데이터 링크 계층(Data Link Layer)

마더 보드에 있는 랜카드를 거치는 단계로 물리적인 링크를 통하여 동기화, 에러 제어, 흐름 제어 등을 통해 패킷을 전송한다. 16진수 12개로 만들어진 MAC 주소를 객체 간 통신에 사용하며, MAC 주소는 고유하다.

물리 계층(Physical Layer)

데이터 베이스 계층으로 랜선을 타고 온 것을 피지컬 레이어라고 한다.

기계적, 전기적, 기능적, 절차적 특성을 정의하며 비트 스트림을 물리 매체를 통해 전송한다.

프로토콜(Protocol)

네트워크에서 프로토콜은 통신 규약을 의미한다.

통신을 할 때 어떠한 규약을 갖고 있다.

대표적 프로토콜은 TCP/IP와 UDP가 있다.

서버를 안하건 기본적으로 알고 있자.

TCP/IP

OSI7Layer을 4단계로 구분한 네트워크 모델로 실제 사용하는 것은 TCP/IP모델이다.

TCP통신은 연결형 통신 서비스로 연결해놓은 상태로 물고있어야 한다.

TCP는 상대방이 받았다는 응답을 받아야만 다음 데이터가 전송 된다.

응답을 받은 다음에 다음 패킷(데이터)을 전송한다.

순차적인 데이터 전송으로 데이터의 전송 순서를 보장한다.

신뢰성있는 데이터 전달과 흐름을 제어한다.

응답을 받았을 때 콜백을 처리해주면 쉽다.

그게 비동기 방식의 처리이다.

비동기 방식의 콜백을 우리가 받아 낼 수 있다.

만드는 것이 아니라 이미 있으므로 쓴다.

ex) PC 두 대에 TCP통신으로 "안녕하세요" 라고 데이터를 보내게 되면

PC 1에서 데이터를 보내면 PC2가 응답을 받아야 다음 데이터가 간다.

받았다는 응답을 보내고, 실패해도 보낸다.

그러면 응답이 또 온다. 이 개념이 끝이다.

UDP

UDP는 비연결형 서비스로 연결없이 통신 가능하다.

UDP는 그냥 IP에다가 패킷을 보내버리는 브로드 캐스팅 방식이다.

정보를 주고 받을때 정보를 주고 받는다는 신호절차를 거치지 않는다.

보내기만 하면 되기 때문에 순차적이지 않아 받는 쪽에서 순서가 바뀔 수 있다.

일방적이고 응답이 없어 속도가 빠르다.

그러나 속도는 빠르나 순서가 바뀔수가 있어 순차적인 데이터 전송이 보장되지 않는다.

ex)

PC A가 그냥 보내기만 함.

PC B가 그냥 보내기만함.

A에서 B로  서버를 거쳐서 패킷을 보내는데 "안녕하세요" 라고 데이터가 전달이 되고,

"또 만났네요"라고 두번째 패킷을 보낼 때는  받는 쪽에서는 첫번째 패킷을 받고 두번째 패킷을 받도록

순서대로 받아야 하는데 순서가 보장이 안돼서

A에서 B로 전송될 때 두 번째 패킷을 보낼때 서버 연결이 돼서 B는

"또 만났네요", "안녕하세요" 순서로 받을 수가 있다.

그래서 게임에서는 보통 TCP를 사용한다.

"안녕하세요" (응답 성공), "또 만났네요" (응답 성공)

이 차이점만 잘 이해하자.

UDP는 TCP에서 소켓 설정만 바꾸면 되는거라 쉽다.

다섯 단계를 거쳐서 A에서 B로 보낼 때 내가 조종하는 것이 아닌, 라우팅이다.

* 라우팅 : 어떤 네트워크 안에서 통신 데이터를 보낼 때 최적의 경로를 선택하는 과정이다.

최적의 경로는 주어진 데이터를 가장 짧은 거리로 또는 가장 적은 시간 안에 전송할 수 있는 경로이다.

ex)전화 통신망, 정보 통신망, 교통망 등 여러 종류의 네트워크에 사용된다.

소켓(Socket)

소켓이란 데이터를 보내고 받게 하는 객체로 소켓을 사용하여 통신할 수 있다. 

소켓 프로그래밍

소켓을 이용해 컴퓨터끼리 통신하는 프로그래밍 방식을 말한다.

기계마다 소켓을 갖고 있으며, 소켓이 있어야지만 소켓가지고 네트워크 통신할 수 있다.

소켓은 네트워크 통신을 하기 위한 기본적인 기능을 갖고 있는 주체이다.

실제 통신을 담당하는 건 물리적으로는 랜선을 통해서 데이터가 오고가지만

이것은 하드웨어이고, 프로그램을 통해서 데이터를 통신하는 것은 소켓이다.

소켓 하나가 클라이언트 하나이다.

소켓이 있어야만 통신이 가능하여 클라이언트 통신을 소켓 통신이라고도 한다.

그러므로 코드를 작성할 때 소켓을 이용해 데이터를 보내고 받는 것을 알아야 한다.

데이터를 보내고 받도록 통신하는 객체가 바로 소켓이다.

이처럼 서버 프로그램을 한다는 것은 소켓을 다루는 것이다.

그래서 소켓 클래스가 필요하다.

그런데 C언어에도 소켓이 존재하기 때문에 소켓을 클래스라고 말할 수는 없다.

객체 대신 주체라는 말을 쓸 수도 있다.

C#에서는 소켓 클래스가 있기 때문에 소켓 객체를 만들어서 사용하면 된다.

소켓을 직접 제작하는것이 아닌 소켓이라는 데이터 타입이 존재한다.

소켓 인스턴스를 만들어서 소켓을 가지고 통신하면 된다.

ex)

PC 하나에 소켓 하나가 있다.

PC와 PC끼리 통신하고자 한다.

데이터를 보낼때 받는 PC입장에서 보내는 PC의 소켓을 알고 있어야 한다.

그러면 같은 응용 프로그램이 설치되어 있을 경우 각각의 소켓으로 통신이 가능하다.

그러면 랜카드를 거쳐 랜선을 타고 전달이 된다.

그러므로 소켓은 당연히 양쪽 PC의 IP를 알고 있어야 한다.

ex)

서버와 각각의 클라이언트가 여러 개가 있을 경우

응용 프로그램을 이용해 서비스를 사용하기 위해 클라이언트는 서버에게 서비스를 요청할 것이다.

서버는 우리 서비스를 사용하는 사용자인지 확인하고 응답을 한다.

로그인 성공 후 클라이언트를 접속한다.

서버 입장에서 여러 명의 클라이언트가 연결되어 있는데, 클라이언트 한 개가 소켓이다.

ex) 채팅 서버

채팅 서버에 접속해 있는 유저가 4명이다.

서버에서 각각의 PC는 소켓으로 알 수 있다.

그러므로 서버 입장에서 각각 다른 소켓을 최소 4개를 갖고 있어야 한다.

유저가 접속을 하게 되면 서버와 통신하라고 소켓을 할당 받는다.

각 클라이언트마다 IP주소를 갖고 있고 서버에서는 이 정보를 소켓으로 알아내는 것이다.

IP 주소(IP Address)

인터넷에 연결된 컴퓨터들의 주소이다.

IP주소에는 IPv6주소와 IPv4 주소가 있다.

IPv4가 숫자 4개로 나타내는 과거부터 사용한 IP이다.

IP사용량이 기하급수적으로 늘어나 네자리 숫자가지고는 IP를 감당할 수 없게 되어

IP6이 추가되고 IP 128bit의 주소 체계를 다시 만들어 냈다.

그래서 PC는 2개의 IP주소를 갖고 있고 IPv4로 표현하는가 IPv6로 표현하는가 차이가 있다.

ex)

2016년이후로 구글과 IOS도 마찬가지로 IPv6 체계로 해야할 것이다.

IPv4 방식으로 했던 온라인 게임들 IPv6로 변경한다.

IPv4

32비트 주소 체계로 4개의 숫자로 표현한다.

IPv6

128비트 주소 체계로 6개의 숫자로 표현한다.

IP 주소 검색 방법

커멘드 창에 ipconfig를 치면 내 PC에 IP를 확인할 수 있다.

cmd창 > ipconfig 검색

ex)

고유IP

PC에서 외부로 데이터가 나가려면 고유 IP주소를 타고 데이터가 나가는 것이다.

유동IP

유동IP는 지역IP , 로컬 주소 , 내부 네트워크 주소이다.

외부로 데이터를 전송할 때는 유동 IP를 가지고 나가는 것이 아닌 고정 IP를 알아야 한다.

ex)

네이버에 자료를 갖고 오고 싶으면 고정IP를 타고 전송하는 것이다.

공유기를 보면 내 PC에 할당된 고정IP가 보여진다.

ex) 사담

고정IP가 하나인 공유기 한 대에 PC 두 세대 돌리면 PC두 대 IP가 몰린 공유기가 있을 수 있다.

공유기가 3, 4개 PC를 갖고 있더라도 데이터는 고유IP 하나를 가지고 나가는 것이다.

공유기 한 대의 사용량을 PC 여러대에서 나누어서 사용하는 개념이다.

IP 한 명분을 신청하고, 그 한 명 분의 IP를 벤드윅스라고 하는데 PC 여러대에서 나눠쓰면 속도가 느려질수 밖에 없다.

통신사에서 PC 별로 통신 사용료를 지불해야 한다고 한다.

그런데 이렇게 사용하지말라고 하지만 일반적으로 그렇게 사용함.

일반적으로 PC한데 신청해놓고 PC에다 공유기 올려놓고 공유기에 여러 PC를 할당해서 사용하는데 속도가 느려진다. 

호스트(host)

네트워크에 연결된 PC를 호스트라고도 한다.

DNS 프로그램 코드 작성할 때 반드시 등장한다.

DNS(Domain Name System)

DNS는 사람이 읽을 수 있는 도메인 이름을 머신이 읽을 수 있는 IP주소 또는 호스트로 변환할 수 있다.

DSN정보를 닷넷에서 알아오는 클래스가 DNS클래스이다.

DNS클래스는 도메인에 관련된 정보를 알아오거나 그러한 기능을 모아놓은 클래스이다.

ex)

www.naver.com, www.daum.net

ex) 구글의 IP와 호스트 정보를 가져오기

구글에 접속하기 위해서 www.google 닷컴으로 접속하면 그게 도메인이고

네트워크 상 안에는 IP주소가 있다.

도메인이 IP주소를 대신하는 호스트 명이 된다.

도메인은 www.으로 시작한다.

DNS를 이용해 www.google.com을 DB가 읽을 수 있는 IP주소로 변환한다.

그 주소를 알아야 어디로 갈지 알 수 있다.

포트(Port)

포트란 PCP가 가지고 있는 주소이자 통로 번호이다.

MAC주소가 네트워크 카드의 고유 식별자이고, IP가 시스템의 논리적인 주소라면

포트는 시스템에 도착한 후 패킷이 찾아갈 응용 프로그램과 통하는 통로 번호이다.

통신을 할 때 IP만 가지고 되는 게 아니라 서버에 포트를 할당해야 한다.

그러므로 PCP를 연결할 포트는 무조건 하나가 필요하다.

포트의 타입은 unsingd short로 0~65535(216)번까지 존재하며, IP나 MAC주소처럼 출발지와 목적지에 응용프로그램별로 포트 번호를 가지고 통신한다. 눈에 띄는 포트를 사용해도 되고, 포트 번호를 섞어서 사용해야 한다.

웰노우 포트 포트

0~1023번 포트까지로 대부분 고유의 사용 용도가 있다.

레지스터드 포트

1024번에서 49151번 중 임의의 포트를 응용 프로그램에 할당하여 사용한다.

다이나믹 포트

다이나믹 포트도 사용하지 말라고 한다.

다이나믹 포트는 49152~65535로서 시스템에서 사용한다.

패킷(Packet)

데이터 전송에서 송신측과 수신측에 의하여 하나의 단위로 취급되어 전송되는 집합체를 의미한다.

즉, 많은 양의 전송 데이터를 수신측으로 이동시키기 위해서 일정 크기로 데이터를 분할하게 되는데, 이 단위 크기로 분할된 하나의 데이터 덩어리를 패킷이라고 한다.

패킷의 종류를 #define 또는 열거체(enum)으로 만들어 놓고 분류를 할 수 있다.

ex)이동 패킷, 스킬 패킷, 귓속말 패킷이야 등등

가변 길이 패킷

- 데이터 길이 + 헤더 + 데이터

- 데이터 길이 + 헤더 + 데이터 + 엔드마커

헤더 : 데이터의 종류를 보내며 클라이언트, 서버가 동시에 갖고 있다.

엔드 마커 : 패킷의 끝을 나타내는 것으로 보통 2byte 정도 할당한다.

ex) 패킷을 전송하기 위한 설계

"안녕하세요"라고 보내고 싶다.

"안녕하세요"는 256byte가 안됀다.

패킷의 첫번째 부분의 1바이트는 데이터의 길이를  명시하고,

두번째 부분의 1바이트는 헤더를 붙일 것이고,

세번째 부분에는 "안녕하세요"라는 데이터를 넣을 수 있다. 

이런식으로 길이 + 헤더 + 데이터 구조로 패킷 데이터를 구성해서 보낸다.

메모리 저장 방식

컴퓨터 메모리에 저장되는 바이트의 순서로 빅엔디안과 리틀엔디안 방식이 있다.  

빅엔디안

빅엔디안은 바이트의 열에서 가장 큰 값부터 저장된다.

리틀엔디안

리틀엔디안은 바이트의 열에서 가장 작은 값부터 저장된다.

ex)

리틀엔디안 방식의 메모리로 "안녕하세요"라는 데이터를 보내면

받은 데로 출력할 경우 "요세하녕안"으로 거꾸로 출력이 될 수 있다.

메모리에 저장된 바이트 순서는 주로 과거의 인텔 계열과 유닉스 계열 차이점인데

인텔 계열에 맞추면 문제가 없다. 이건 CPU가 결정한다.

동기와 비동기

네트워크 프로그래밍 하면서 핵심적인 내용은 동기와 비동기이다.

동기 방식(Synchronous)

동기 방식은 함수가 끝난 다음에 다음 함수가 호출이 된다.

동기화는 클라와 서버를 동시에 돌려야 하지만 데이터 전송하고 받는 건 문제가 안되는데

클라에서 동기화를 하려면 클라이언트 문제가 맞다.

프레임스킵을 구현할 줄만 알면 동기화가 된다.

프레임이 일정 프레임 아래로 내려갔을 때 스킵을 구현할 줄 알면 동기화가 된다.

그러나 유니티에서 프레임 스킵 구현이 쉽지가 않다.

비동기(Asynchronous)

요청을 보낸 후 응답과는 상관없이 다음 방식이 동작한다.

서버는 비동기 방식으로 만들어야 효율이 좋다.

동기 방식 서버도 사용이 되기는 한다.

함수 이름앞에 Asynch란 말이 붙으면 비동기라는 의미가 된다.

ex)

서버에서 유저 로그인 처리시 1000명이 접속할 경우

동기 방식으로 만들면 한명 접속 처리하고 모두 완료한 다음에 두번 접속 처리, 완료한 다음에 세번째 접속처리..

비동기 방식의 로그인을 만들게 되면 비동기 방식은 한명 접속 요청이 오게 되면 처리하라고 던져놓고 두번째 유저를 받는다. 처리가 끝나고 안끝나고는 중요하지 않고 그걸 처리하는 건 따로 있다.

다음 유저를 바로바로 받는다. 대기하고 있는 유저를 또 던져놓고 다음 유저를 또 던져 놓는다.

그래서 동기 방식보다 비동기 방식이 빠르다.

C와 C++기반의 IO CP를 별도로 구성을 해야하는데

C#에서는 다른 방식으로 구현할 수 있어서 편리하다.

스레드

프로세스 안에 스레드라는 개념이 존재한다.

스레드는 어떠한 작업을 하기 위해서 별도로 구동되는 실행 단위이다.

CPU 하나를 스케줄링해서 실행된다.

실행 파일인 프로세스 안에는 여러 개의 스레드가 존재 한다.

여러 개의 스레드 중에서 메인 역할을 하는 스레드가 메인 스레드이다.

메인 스레드에서 메인 함수를 호출하는 것이다.

멀티 스레드

멀티스레드는 어떠한 작업을 동시 작업하는 것으로 스레드가 여러 개가 구동되면 멀티 스레드 방식 처리이다.

스레드가 여러 개가 구동된다는 말은 이 작업을 하기 위해서 메인 스레드 하나만 사용하는게 아니라 그 작업을 동시 작업 시키는 것으로 멀티 테스킹이라고 한다.

사실 동시 작업이라는 개념은 PC에 존재하지 않고 CPU를 나눠 쓰는 방식이다.

스레드를 동시에 실행되는 개념이 아니라 시간 할애를 해주는 것이다.

스레드A 한 번, 스레드B 한 번,,, 빠르게 반복되다 보니까 동시 작업하는 것처럼 보인다.

유니티는 C# 닷넷을 주로 사용하고 서버와 클라이언트의 네트워크 프로그래밍이 가장 쉬운 방식이다.

그래서 언어를 같이 맞춰서 사용한다.

서버를 하려면 스레드 개념이 있어야 한다.

유니티에서 스레드를 사용하지 않고도 비동기 방식 서버를 구동시킬 수 있는 것은 닷넷에서 비동기 방식 함수들을 다 만들어 주었기 때문이다. 초창기에 비동기 방식을 만드려고 클래스 매핑도 하고 자구적인 노력으로 다 만들어서 닷넷은 네트워크 통신이 편하게 되어있다. 지금 배우고있는 것이 닷넷 기반의 서버이다.

네트워크 공부는 어렵지는 않지만 테스트 환경이 쉽지 않다.

ex) 서버에 몰려있는 PC가 최대 500~1000대 일반적으로 MMORPG 서버는 3000명 수용이 가능한게 일반적이다.

3000명이 붙었을 때 어떤일이 일어날지 모른다.

디버깅 할 경우 브레이크 포인트를 걸어두면 다른사람들을 멈춘다. 코드가 진행이 안돼니까

클라이언트가 잘못되더라도 PC하나 죽지만 서버가 잘못되면 서버에 붙어있는 모든 클라이언트가 잘못되므로 조심해야 한다. 

서버 프로그래밍 공부시 복잡한 쿼리는 아니더라도 데이터베이스에 의해서 로그인부터해서 레벨업을 DB에 반영해서 서버로부터 다시 넘겨받는 연습을 해보자.

유니티 연동해서 한 세트 만들어서, 서버 기반 움직임 지원하기

서버 프로그램

서버 프로그램을 하기 위해서 어떠한 구조와 순서로 서버 프로그래밍을 구성해야 하는지 먼저 이해해야 한다.

네트워크 통신의 순서가 정해져 있으며, 그 순서대로 소켓을 구동시켜야 한다.

네트워크 통신 순서

네트워크 통신 순서로 서버 프로그램을 만들면 된다.

이 순서로 네트워크 함수를 호출하면 된다.

유저 접속

먼저 서버에서 필요한 것은 유저 접속을 처리하는 소켓이다.

유저 접속을 처리하는 소켓은 bind - listen - accept 순서로 호출하면 된다.

먼저 bind()로 서버를 연결하고

Listen()을 호출하여 새로운 클라이언트가 접속했는지 대기하고 있다가

새로운 클라이언트가 connect()하여 접속 요청을 하면 서버는 accept()를 하게 된다.

accept()가 호출되었을 때 접속한 클라이언트와 통신하라고 소켓 하나를 리턴해준다.

그 소켓을 가지고 클라이언트와 통신하면 된다.

그리고 클라이언트에 전송할 패킷이 있다면 그 소켓을 통해서 해당 클라이언트한테 전송을 해주면 된다.

데이터를 보내게 되면 그 소켓을 통해서 전달이 된다.

그래서 서로 데이터를 주고 받으면 클라이언트 입장에서는 게임을 종료하면

소켓을 클라이언트는 닫아주고, 서버에서도 할당했던 소켓을 닫아주고 그 소켓을 리스트에서 지워주면 된다.

C#은 네트워크 프로그래밍시 웬만한 클래스를 만들어서 제공하기 때문에 사용하기가 편함.

닷넷에서 미리 만들어 놓은 서버가 있기 때문에 서버 모듈을 일일이 하나씩 안만들어도 된다.

닷넷에서 이미 C# Listenner 클래스를 만들었으며 서버 기능이 다 가능하며 성능도 똑같다.

이어서 오는 방식으로 Stream방식을 지원한다.

ex)

네트워크에서는 데이터를 전송하게 되면

"안녕하세요" 전송시 "안녕"까지 오고 "하세요"가 나중에 올 수도 있다.

그게 데이터가 연속되게 온다는 보장이 없다.

과거의 서버는 어떻게 작업했는가.

바이트 단위로 전송하는데 바이트를 계속 이어붙이는 코드를 만들어 놓고 구동을 시켜야 한다.

바이트 단위 전송이기 때문에 바이트를 계속 이어서 붙일 수 있게 서비스하는 언어가 C++이다.

그리고 그 부분을 뺄 수 있는게 C#서버이다.

C# Stream 방식은 이어서 온다. 않끈김, 끊기더라도 이어서 온다.

C#서버에서도 바이트 단위로 이어서 패킷을 완성하는 방식으로 사용할 수 있으나

Stream 방식을 할 수있어 그렇게 할 필요가 없다.

서버 프로그래머가 아니더라도 네트워크 통신은 기본이다.

온라인 게임을 만드는데는 반드시 네트워크 개념이 있어야 한다.

비정상적인 처리와 종료 처리 등의 예외 처리를 신경써야 한다.

패킷을 직접 수동으로 이어붙일 필요가 없기 때문이다.

서버가 어려운 이유는 여러 명이 다수의 사용자가 접속할 때는 우리가 모르는 ,경험하지 못한 상황이 많이 발생하며

그래픽컬하지 않아 논리적으로 구동되기 때문에 디버깅이 쉽지 않다.

또한 서버에서 디버그 모드시 코드가 진행되다 중단점에 진입시  다른 클라이언트는 아무것도 못한다.

서버는 한 번 블럭이 되서 코드가 진행이 안돼는 상태면 전체가 서비스를 이용을 못하는 것이다.

코드가 하나 틀리게 되면 그게 어렵기 때문에 경력자를 채용하는 편이다.

디버그 모드를 쉽게 할 수 없다.

그러나 네트워크 통신 순서대로만 하면 된다.

서버의 기술

서버를 어떻게 구분하느냐도 중요하다.

서버는 PC 하나의 단위(워크프로세서 단위)가 아닌 프로세스(실행 파일)단위이다.

또 서버와 서버 간에 통신을 해야 함. 동기화를 해야 다른 프로그램이 구동 되고 있다.

ex) 로그인 서버, NPC 서버, 게임 서버 이렇게 있다고 하면

채팅 서버, 몬스터 서버의 실행 파일 단위로 논리적으로 구분해서 사용할 수 있다.

몬스터 서버는 몬스터만 관리, 게임 서버는 게임 서버만 관리한다고 해보자.

우리 눈에 보이는 게임 공간에는 몬스터가 존재, 게임 공간 존재

그런데 몬스터는 다른 프로그램에서 도는 것, 근데 몬스터는 따로 놀 수 없다.

이 두 개를 어떻게 맞출것인가 이런게 서버 프로그래머가 해야할 일이다.

ex)

또한 서버는 수용량이 중요하다.

서버를 한 번 만들어 놨는데 몇명 수용되는 서버인가, 클라이언트와 서버는 윈도우 기반이 맞는데

그래픽 유저 인터페이스 기반의 서버를 만들어 리소스 시스템 자원을 사용하게 되면, 수용량이 떨어지게 된다.

ex)

윈도우 서버 1000명, 리눅스 서버 3000명

MSSQL 또는 MYSQL이냐에 따라 비용적인 부분도 있다. 

ex)

MMORPG 게임 서버 유지 비용은?

한 달에 서버만 유지 하는데 유지 비용만 몇천만원이 나간다.

회사 입장에서 비용적인 측면에서 서버 하나를 만들어 놓으면

물리 적인 서버에 수용할 수 있는 수용량은 늘리고 사용량은 줄여야 한다.

그래서 패킷을 잘 설계해야 함. 패킷을 한번에 처리할 수 있는 것을 두번에 처리하면 사용량이 두 배로 늘어난다.

서버가 클라이언트 보다 오히려 손은 많이 안가지만 한 번 문제가 발생하면 신중히 해결해야 함.

그리고 사람마다 유저 접속을 처리하는 실제 클라이언트 소켓을 accept 함수가 처리한다고 했다.

유저 하나당 소켓을 하나 사용하거나, 소켓을 둘을 사용할 수 있다.

할당을 그렇게 해놓는 것이다.

유저 하나당 소켓 하나를 만들거나 둘로 만드는 것은 게임마다 다름.

ex) 통신시 보내기 소켓 전용, 받기 전용 소켓으로 둘 수도 있다.

서버를 잘하다는 말 = 서버의 구동과 몇명까지 수용이 가능한가

클라이언트는 FPS 몇프레임이 나오고 서버는 몇명까지 수용가능한지

그래서 처음에 유저가 선택을 하게 해서 서버에 들어가게 하고

그래서 유저가 꽉차면 혼잡 원할 이런식으로 보여준다.

이걸 어떻게 판단하는가

사용량, CPU사용량, 메모리 사용량으로 수용량을 정할 수 있다.

어느 서버에 내 계정이 있는데 다른 서버로 옮겨달라.

이건 독립적인 것으로 데이터베이스와 다르다.

Toplist

최신 우편물

태그