본문 바로가기
cs공부/네트워크프로그래밍

네트워크 프로그래밍 - C# 간단한 blocking 사용한 Server 소켓프로그래밍 구현

by 코딩하는 돼징 2023. 6. 19.
반응형

소켓프로그래밍 과정 알아보러가기

 

네트워크프로그래밍 - 소켓 프로그래밍(클라이언트 관점, 서버관점) 과정

손님 관점 클라이언트 관점 핸드폰 준비 소켓(클라이언트와 서번 간의 데이터 송수신을 가능하게 해준다) 준비 식당 번호로 연락한 다음 식당 입장 가능한지 문의 소켓을 통해서 서버의 주소로

code-piggy.tistory.com


Client코드 보러가기

 

네트워크 프로그래밍 - C# 간단한 Client 소켓프로그래밍 구현

소켓 프로그래밍 과정 알아보러 가기 네트워크프로그래밍 - 소켓 프로그래밍(클라이언트 관점, 서버관점) 과정 손님 관점 클라이언트 관점 핸드폰 준비 소켓(클라이언트와 서번 간의 데이터 송

code-piggy.tistory.com


1. Visual Studio 설정하기

Client, Server 동시에 작업할 수 있도록 세팅하기


1. Socket준비

01 Dns.GetHostName

현재 실행 중인 컴퓨터의 호스트 이름을 가져온다.

using System.Net;
public static string GetHostName ();

string host = Dns.GetHostName();

DNS(Design Name Socket)란

인터넷에서 도메인 이름과 IP 주소를 매핑하는 시스템이다. 도메인 이름을 IP주소로 해석하거나 IP주소를 도메인 이름으로 변환하는 역할을 한다.

ex) www.code-piggy.tistory.com  -> 111,1,1,1


2. Dns.GetHostEntry

지정된 호스트의 이름 또는 IP주소에 대한 네트워크 정보들을 얻어올 수 있다.

using System.Net;
public static System.Net.IPHostEntry GetHostEntry (string hostNameOrAddress);

반환

IPHostyEntry : 호스트에 대한 다양한 정보가 포함되어있는 클래스이다.


IPHostEntry iphost = Dns.GetHostEntry(host);

3. IPhostEntry포함되어 있는 정보들

01 HostName

호스트 이름

public string HostName { get; set; }

02 AddressList

호스트에 연결된 IP주소 목록

public System.Net.IPAddress[] AddressList { get; set; }

03 Aliases

호스트에 대한 대체 이름이나 별명을 나타내는 목록

public string[] Aliases { get; set; }

IPAddress ipAddr = iphost.AddressList[0];

4. IPEndPoint

IP주소와 port번호(어디다가 전달되어되는지)의 조합으로 구성되며 특정 서버 또는 클라이언트의 위치를 식별하면서 특정 호스트 서비스에 접속하는데 사용된다.

public IPEndPoint (System.Net.IPAddress address, int port);

 

IP주소 : 식당의 주소

port번호 : 식당의 문 번호


IPEndPoint endPoint = new IPEndPoint(ipAddr, 7777);

5. IPEndPoint Property

01 Address

public System.Net.IPAddress Address { get; set; }

02 Port

public int Port { get; set; }

03 AddressFamily

IP주소 체계 정보, 이를 통해 IPv4인지 IPv6인지 확인할 수 있다.

public override AddressFamily AddressFamily { get; }

05 Socket준비 전체 코드

string host = Dns.GetHostName();
IPHostEntry iphost = Dns.GetHostEntry(host);
IPAddress ipAddr = iphost.AddressList[0];
IPEndPoint endPoint = new IPEndPoint(ipAddr, 7777);

6. Sokcet 객체 생성

public Socket(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType);

매개변수

adressFamily : 소켓의 주소 체계

socketType : 소켓 유행 (SocketType.Stream은 TCP 소켓, SocketType.Dgram는 UDP소켓)

protocalType : 프로토콜 유형 (ProtocolType.Tcp은 TCP 프로토콜, Protocoal.Udp는 UDP 프로토콜)


// 문지기 핸드폰 만들어주기
Socket listenSocket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

7. Socket 초기화 및 대기

01 socket.Bind

Socket을 특정 IP주소와 port번호에 바인딩한다. 이는 해당 주소와 번호가 들어오면 연결을 처리할 수 있다.

public void Bind(EndPoint localEP);

02 socket.Listen

Socket을 연결 요청 대기 상태로 설정한다. 이는 해당 포트번호로 들어오는 클라이언트의 연결 요청을 backlog에 지정한 수 까지 대기시킬 수 있다.

public void Listen(int backlog);

// 문지기 교육
listenSocket.Bind(endPoint);

// 영업 시작
// backing : 최대 대기 수
listenSocket.Listen(10);

8. 클라이언트 연결

01 클라이언트 연결 기다리기

while (true)
{
    Console.WriteLine("Listening...");
}

연결이 성공된 경우

02 Accept

클라이언트의 연결 요청을 수락하고 클라이언트와 통신하기 위한 새로운 소켓을 반환한다.

public Socket Accept();

연결이 실패한 경우

catch(Exception e)
{
    Console.WriteLine(e.ToString());
}

while (true)
{
    Console.WriteLine("Listening...");

    // 손님을 입장시킨다.
    Socket clientSocket = listenSocket.Accept();
}

9. 클라이언트에서 온 데이터 받기

01 수신된 데이터 저장할 공간 만들기

byte[] recvBuff = new byte[1024];

02 socket.Receive

Socket객체를 사용하여 데이터를 받는다.

 

public int Receive(byte[] buffer);

 int recBytes = clientSocket.Receive(recvBuff);

03 Encoding.UTF8.GetString

public virtual string GetString(byte[] bytes, int index, int count);

매개변수

bytes : 변환할 byte 배열

index : 변환을 시작할 byte의 index

count : 변환할 byte의 수

string recvData = Encoding.UTF8.GetString(recvBuff, 0, recBytes);
Console.WriteLine($"[From Client] {recvData}");

byte[] recvBuff = new byte[1024];
int recBytes = clientSocket.Receive(recvBuff);
string recvData = Encoding.UTF8.GetString(recvBuff, 0, recBytes);
Console.WriteLine($"[From Client] {recvData}");

10. 서버에서 클라이언트로 데이터 보내기

01 Encoding.UTF8.GetBytes

문자열을 UTF-8인코딩을 사용하여 바이트 배열로 변환한다.

public virtual byte[] GetBytes(string s);

02 socket.send

Socket객체를 사용하여 서버나 다른 소켓으로 데이터를 보내는 역할을 한다.

public int Send(byte[] buffer);

byte[] sendBuff = Encoding.UTF8.GetBytes("Weclome to code-piggy Server !");
clientSocket.Send(sendBuff);

11. Socket 종료

01 socket.Shutdown

Socket객체의 연결을 종료시킨다.

public void Shutdown(SocketShutdown how);

how 종류

SocketShutdown.Receive : Sokcet 수신 기능 종료

SocketShutdown.Send : Socket 송신 기능 종료

SocketShutdown.Both : Socket 수신 및 송신 기능 종료


02 socket.Close

Socket은 현재 연결을 종료하고 리소스를 정리한다. 이를 통해 연결을 안전하게 종료시킬 수 있다. 

public void Close();

clientSocket.Shutdown(SocketShutdown.Both);
clientSocket.Close();

12. 코드

try
{
    listenSocket.Bind(endPoint);
    listenSocket.Listen(10);

    while (true)
    {
        Console.WriteLine("Listening...");
        Socket clientSocket = listenSocket.Accept();

        // 받는다
        byte[] recvBuff = new byte[1024];
        int recBytes = clientSocket.Receive(recvBuff);
        string recvData = Encoding.UTF8.GetString(recvBuff, 0, recBytes);
        Console.WriteLine($"[From Client] {recvData}");
        
        // 보낸다
        byte[] sendBuff = Encoding.UTF8.GetBytes("Weclome to code-piggy Server !");
        clientSocket.Send(sendBuff);
        
        // 나간다
        clientSocket.Shutdown(SocketShutdown.Both);
        clientSocket.Close();
    }

}
catch(Exception e)
{
    Console.WriteLine(e.ToString());
}

13. 결과 확인

 


Non-blocking방식 이용한 Server코드

 

네트워크프로그래밍 - C# 간단한 Non - blocking 사용한 Server 소켓프로그래밍 구현

blocking방식 이용한 Server코드 네트워크 프로그래밍 - C# 간단한 Server 소켓프로그래밍 구현 소켓프로그래밍 과정 알아보러가기 네트워크프로그래밍 - 소켓 프로그래밍(클라이언트 관점, 서버관점)

code-piggy.tistory.com


 

 

 

 

 

 

 

참고 :  본 내용은 MMORPG  PART4 강의를 수강하여 작성하였습니다.

https://www.inflearn.com/course/%EC%9C%A0%EB%8B%88%ED%8B%B0-mmorpg-%EA%B0%9C%EB%B0%9C-part4

 

 

 

 

 

반응형

댓글