코다람쥐 2022. 3. 12. 23:08

1. 소켓 프로그래밍 설명

손님-식당의 경우
손님
1) 핸드폰 준비
2) 식당 번호로 입장 문의
휴대폰을 통해 대리인 휴대폰과 통화 가능


식당
1) 문지기 고용
2) 문지기 교육(식당 번호 알려줌)
3) 영업 시작
4) 안내
손님 대리인을 통해 손님과 통화 가능
클라이언트-서버의 경우
클라이언트
1) 소켓 준비
2) 서버 주소로 Connect
소켓을 통해 Session 소켓과 패킷 송수신 가능


서버
1) Listener 소켓 준비
2) Bind(서버 주소/Port를 소켓에 연동)
3) Listen
4) Accept
클라 세션을 통해 손님과 통화 기능

 

2. 클라이언트-서버 구현

Server구현

using System;
using System.Net; // Dns 사용을 위해 선언
using System.Net.Sockets;// Socket 사용을 위해 선언
using System.Text; // Encoding 사용을 위해 선언
using System.Threading;
using System.Threading.Tasks;

namespace ServerCore
{
    class Program
    {
        static void Main(string[] args)
        {
            // DNS(Domain Name Syetem)
            string host = Dns.GetHostName(); // 호스트 이름 추출
            IPHostEntry ipHost = Dns.GetHostEntry(host); // 호스트 이름을 통해
            IPAddress ipAddr = ipHost.AddressList[0];    //  ip주소 추출
            IPEndPoint endPoint = new IPEndPoint(ipAddr, 7777); // 최종주소, 2번째 인자는 포트번호

            // 문지기
            Socket listenSocket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); // IPv4, TCP사용 

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

                // 영업 시작
                listenSocket.Listen(10); // 최대 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); // 0번째 인덱스부터 문자를 받음 
                    Console.WriteLine($"[From Client] {recvData}");

                    // 보낸다
                    byte[] sendBuff = Encoding.UTF8.GetBytes("Welcome to MMORPG Server");
                    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;

namespace DummyClient
{
    class Program
    {
        static void Main(string[] args)
        {
            // DNS(Domain Name Syetem)
            string host = Dns.GetHostName(); // 호스트 이름 추출
            IPHostEntry ipHost = Dns.GetHostEntry(host); // 호스트 이름을 통해
            IPAddress ipAddr = ipHost.AddressList[0];    //  ip주소 추출
            IPEndPoint endPoint = new IPEndPoint(ipAddr, 7777); // 최종주소, 2번째 인자는 포트번호

            // 휴대폰 설정
            Socket socket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);

            try
            {
                // 문지기한테 입장 문의
                socket.Connect(endPoint);
                Console.WriteLine($"Connected to {socket.RemoteEndPoint.ToString()}");

                // 보낸다
                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());
            }            
        }
    }
}