서버 22

RecvBuffer 개선

RecvBuffer 개선TCP에서 클라이언트에서 100바이트를 보낸다고 가정하면 TCP의 특성 상, 무조건 100바이트가 온다는 보장이 없다. 만약, 80바이트만 도착했다면, RecvBuffer 에서 저장하고 있다가 나중에 20바이트가 도착하면 합쳐서 한번에 처리할 수 있도록 해야 한다. 우선, ServerCore에 RecvBuffer class를 추가하자. RecvBufferusing System;using System.Collections.Generic;using System.Text;namespace ServerCore{ public class RecvBuffer { // 얘가 버퍼가 되는 거. 10바이트짜리 배열이라고 가정을 하고 진행을 한다. /..

TCP vs UDP

TCP vs UDPTCP와 UDP는 전송을 어떻게 할 건지 확인하고, 오류를 어떻게 처리할지 결정하는 트랜스포트의 종류이다. 지난번 간략히 설명을 했지만, 조금 더 구체적으로 정리해보자. 우리는 TCP를 이용해서 구현할 예정이고, TCP가 복잡한 과정 없이 간편히 사용할 수 있다. https://kkln2486.tistory.com/507 네트워크 기초 이론네트워크 기초 이론 네트워크 위와 같이 고객, 경비실, 아파트 단지, 택배 배송 센터에서 택배를 보내는 것을 예를 들어서 설명할 수 있다. 같은 아파트 단지 내에 있는 다른 고객에서 택배를kkln2486.tistory.com TCP / UDP 예시TCP : 안전한 트럭, 전화 연결 방식UDP : 위험한 오토바이 총알 배송, 우편 전송 방식 TCP와..

Connector 구현

Connector 구현Session을 수정했던 것 처럼, Connect 함수 부분도 블로킹 방식에서 비동기 함수로 수정해줘야 한다. ServerCore에 Connector 클래스를 추가하자. Listener을 구현할 때와 유사한 구조로 진행한다. Server에 Connector가 필요한 이유?Server는 대기 상태에서 Client의 연결을 기다리는 역할을 하는데 왜 Connector가 필요할까? Server와 Client의 연결 뿐만 아니라, Server와 Server 끼리 통신을 할 때도, 한쪽은 Listener, 다른 한쪽은 Connector를 사용해서 통신한다. ServerCore 셋팅이제 ServerCore에 추가했던 class들은 모두 Client에서 사용할 수 있어야 한다. 그렇다고 ..

Session 구현

Session 구현Listener class를 따로 만들어서 보완했던 것 처럼, Receive, Send 함수 부분도 블로킹 방식에서 비동기 방식으로 보완을 해야한다. Receive는 Listener과 비슷하지만, Send는 조금 더 복잡하다. 먼저, ServerCore에서 Session class를 추가하자. 코드 작성 및 수정Sessionusing System;using System.Collections.Generic;using System.Net;using System.Net.Sockets;using System.Text;using System.Threading;namespace ServerCore{ abstract class Session { Socket _socket; ..

Listener 구현

Listener 구현이전에 예시로 만든 소켓 프로그래밍 구조는 문제점이 있다. 그것은 바로 블로킹 방식을 사용해서 받아올 것이 없을 때, 코드가 멈출 수 있는 것이다. 그래서 비동기 방식으로 수정하는 보완이 필요하다.   우선 ServerCore에 Listener class를 추가하자.  Listenerusing System.Net;using System.Net.Sockets;namespace ServerCore{ class Listener { private Socket _listenSocket; private Action _onAcceptHandler; public void Init(IPEndPoint endPoint, Action onAcceptHand..

소켓 프로그래밍 기초

소켓 프로그래밍 기초소켓 프로그래밍도 식당의 예를 들어서 설명할 수 있다. 운영할 준비가 된 식당이 있다고 가정하자. 식당에는 문과 문지기가 있고, 손님은 이 식당의 문지기에게 휴대폰으로 식당에 자리가 있는지 물어보고, 자리가 있으면 친구를 먼저 보내서 상황을 전달 받을 수 있다.  손님의 입장 (클라이언트)휴대폰 : 소켓손님 : 클라이언트친구 : 클라이언트 Session식당 번호로 입장 문의 : 서버 주소로 연결휴대폰을 통해 친구와 연락 : 소켓을 통해 Session 소켓과 패킷 송수신 가능클라이언트가 서버에 접속을 하면, 서버에서 기타 처리를 한 뒤, Session을 하나 만들어서 모든 통신은 이 Session을 통해 이루어진다.  식당의 입장 (서버)문지기 고용 : Listen 소켓 준비문지기 교육..

네트워크 기초 이론

네트워크 기초 이론 네트워크 위와 같이 고객, 경비실, 아파트 단지, 택배 배송 센터에서 택배를 보내는 것을 예를 들어서 설명할 수 있다. 같은 아파트 단지 내에 있는 다른 고객에서 택배를 발송할 때는 고객 -> 경비실 -> 고객의 경로로 택배를 보낼 수 있다. 이때, 택배를 보낼 때는 A 아파트 101호 -> A 아파트 102호와 같이 주소를 남겨야한다. 단, 같은 아파트 단지 내이기 때문에 주소 대신 간략하게 철수 -> 영희 와 같이 표시를 할 수도 있다. 다른 아파트 단지로 택배를 보낼 경우에는 A 아파트 101호 -> B 아파트 101호 와 같이 경비실에 택배와 주소를 맡긴다. 그리고 경비실에서는 주소를 확인하고 다른 아파트 단지라는 것을 확인한 뒤, 택배 배송센터에 보내게 된다. 그리고 택배 ..

Thread Local Storage (TLS)

Thread Local Storage (TLS)멀티 쓰레드 환경이라고 무조건 Lock을 거는 것은 효율적이지 않다. MMO RPG의 경우 여러 유저들이 동시에 한 곳에 각각 패킷을 보내는 경우가 많이 때문에 이때는 Lock을 거는 것은 과부하가 걸릴 수 있다. 무조건 Lock을 걸어서 멀티 쓰레드 환경을 구축하는 것도 가능은 하지만, 경우에 따라서는 (MMO RPG 같은) 무조건 Lock을 걸면 안된다는 것이다.  ex) 식당에서 각각의 점원들은 서로의 구역에 어느정도 상호작용하고 있고, 한번에 여러 직원이 같은 구역에 몰릴 가능성도 있다. 이렇게 한 곳에 동시에 패킷을 보내는 경우, 각각 Lock을 걸어서 처리하는 것이 아니라 공통적인 부분은 함께 같이 처리하는 방법이 필요하다. ex) 식당의 여러 테..

Lock 구현

Spin Lock변수를 점유할 때 까지 쉬지않고 계속 점유를 시도하는 방법 ex) 화장실에서 사람이 나올때 까지 대기  Spin Lock 구현1. 만약 Lock을 다른 쓰레드가 소유하고 있으면, 해당 Lock이 풀릴때 까지, 무한루프를 돈다.2. 만약 Lock을 소유하고 있는 쓰레드가 없다면, 해당 Lock을 얻고, 이제는 소유중이라고 Lock의 상태를 변경한다. 이 두가지 조건을 만족하는 코드를 작성해보자.  using System;using System.Threading;using System.Threading.Tasks;namespace CSharp{ class SpinLock { // 상태 volatile bool _locked = false; //..

데드락 (DeadLock)

데드락 (DeadLock) 데드락(Deadlock)은 컴퓨터 과학에서 여러 프로세스나 스레드가 서로를 무한히 기다리는 상태를 말한다. 이 상태에서는 모든 관련 프로세스나 스레드가 정지 상태에 빠져, 작업을 계속할 수 없게 된다. ex) 화장실에는 두개의 자물쇠가 있다고 가정. 서로 다른 사람이 각각 하나의 자물쇠를 가지면 둘다 잠글 수 없는 데드락 상태가 발생한다. 그래서 1번 자물쇠부터 가지고, 2번 자물쇠를 가지도록 약속을 해야한다.   namespace ServerCore{ class SessionManager { static object _lock = new object(); public static void TestSession() { ..