소켓 통신 실행 흐름

 

Step 0. 최소 동기 클라이언트 (기본 뼈대)

더보기
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

class Step0_Minimal
{
    static void Main()
    {
        //(1)
        Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

        //(2)
        sock.Connect(IPAddress.Loopback, 23000);

        //(3)
        byte[] buffSendsend = Encoding.UTF8.GetBytes("hello");
        sock.Send(buffSendsend); // ⚠️부분 전송 가능성 있음(아래 단계에서 보완)

        //(4)
        byte[] recv = new byte[1024];
        int n = sock.Receive(recv); // ⚠️메시지 경계 모호
        Console.WriteLine(Encoding.UTF8.GetString(recv, 0, n));

        //(5)
        sock.Shutdown(SocketShutdown.Both);
        sock.Close();
    }
}
소스코드를 붙여넣습니다.
프로그램을 실행하면
서버가 동작하지 않을 때, 비정상적인 에러가 발생합니다.


Step 1. try ~ catch

더보기
해당 부분을 블럭 씌우고, 단축키 Ctrl+K, Ctrl+S 키를 입력합니다.
코드 스니펫이 동작하면, try 키워드로 검색 후 선택합니다.
블럭 씌워진 코드 부분이 try catch 문으로 자동으로 감싸지게 됩니다.
// + 수정 Step 1.
catch (SocketException se) when (se.SocketErrorCode == SocketError.ConnectionRefused)
{
    Console.WriteLine("⚠️ 연결 거절: 해당 주소/포트에서 서버가 수신 중이 아닙니다.");
    Console.WriteLine("- 서버가 실행 중인지 확인");
}
catch (SocketException se)
{
    Console.WriteLine($"소켓 예외: {se.SocketErrorCode} - {se.Message}");
}
catch (Exception ex)
{
    Console.WriteLine($"예상치 못한 오류: {ex}");
}
finally
{
    //(5)
    if (clientSocket != null)
    {
        if (clientSocket.Connected)
            clientSocket.Shutdown(SocketShutdown.Both);

        clientSocket.Dispose();// Close() 생략 가능 (Dispose가 Close 포함)
    }

    //string stop = Console.ReadLine();
}
소켓예외 처리를 위한 catch 코드와, finally 부분을 추가합니다.
프로그램을 실행하면
예외 상황 없이, 프로그램이 정상 동작 후, 종료되었습니다.


Step 2. 수정

더보기
//(2) + 수정 Step 2.
IPAddress? ipaddr = null;

Console.WriteLine("*** 소켓 클라이언트 시작 예제에 오신 것을 환영합니다. ***");
Console.WriteLine("서버의 IP 주소를 입력하고 Enter 키를 누르세요: ");

string? strIPAddress = Console.ReadLine();

Console.WriteLine("유효한 포트 번호(0~65535)를 입력하고 Enter 키를 누르세요: ");
string? strPortInput = Console.ReadLine();
int nPortInput = 0;

if (strIPAddress == " ") strIPAddress = "127.0.0.1";
if (strPortInput == " ") strPortInput = "23000";

if (!IPAddress.TryParse(strIPAddress, out ipaddr))
{
    Console.WriteLine("잘못된 서버 IP가 입력되었습니다.");
    return;
}
if (!int.TryParse(strPortInput?.Trim(), out nPortInput))
{
    Console.WriteLine("잘못된 포트 번호가 입력되었습니다. 프로그램을 종료합니다.");
    return;
}

if (nPortInput <= 0 || nPortInput > 65535)
{
    Console.WriteLine("포트 번호는 0 이상 65535 이하의 값이어야 합니다.");
    return;
}

Console.WriteLine($"서버 정보 → IP 주소: {ipaddr} / 포트: {nPortInput}");

clientSocket.Connect(ipaddr, nPortInput);

Console.WriteLine("서버에 연결되었습니다!");

 

//(3) + 수정 Step 2.
Console.WriteLine("텍스트를 입력 후 Enter 키를 누르면 서버로 전송됩니다.");
Console.WriteLine("프로그램을 종료하려면 <EXIT> 을 입력하세요.");

string inputCommand = string.Empty;

while (true)
{
    inputCommand = Console.ReadLine() ?? string.Empty;

    if (inputCommand.Equals("<EXIT>"))
    {
        break;
    }

    byte[] buffSend = Encoding.ASCII.GetBytes(inputCommand);

    //(4)
    clientSocket.Send(buffSend);

    byte[] buffReceived = new byte[128];
    int nRecv = clientSocket.Receive(buffReceived);

    Console.WriteLine("서버로부터 수신한 데이터: {0}", Encoding.ASCII.GetString(buffReceived, 0, nRecv));
}

 

수정된 전체 코드

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

class Client01
{
    static void Main()
    {
        //(1)
        Socket clientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

        try
        {
            //(2) + 수정 Step 2.
            IPAddress? ipaddr = null;

            Console.WriteLine("*** 소켓 클라이언트 시작 예제에 오신 것을 환영합니다. ***");
            Console.WriteLine("서버의 IP 주소를 입력하고 Enter 키를 누르세요: ");

            string? strIPAddress = Console.ReadLine();

            Console.WriteLine("유효한 포트 번호(0~65535)를 입력하고 Enter 키를 누르세요: ");
            string? strPortInput = Console.ReadLine();
            int nPortInput = 0;

            if (strIPAddress == " ") strIPAddress = "127.0.0.1";
            if (strPortInput == " ") strPortInput = "23000";

            if (!IPAddress.TryParse(strIPAddress, out ipaddr))
            {
                Console.WriteLine("잘못된 서버 IP가 입력되었습니다.");
                return;
            }
            if (!int.TryParse(strPortInput?.Trim(), out nPortInput))
            {
                Console.WriteLine("잘못된 포트 번호가 입력되었습니다. 프로그램을 종료합니다.");
                return;
            }

            if (nPortInput <= 0 || nPortInput > 65535)
            {
                Console.WriteLine("포트 번호는 0 이상 65535 이하의 값이어야 합니다.");
                return;
            }

            Console.WriteLine($"서버 정보 → IP 주소: {ipaddr} / 포트: {nPortInput}");

            clientSocket.Connect(ipaddr, nPortInput);

            Console.WriteLine("서버에 연결되었습니다!");

            //(3) + 수정 Step 2.
            Console.WriteLine("텍스트를 입력 후 Enter 키를 누르면 서버로 전송됩니다.");
            Console.WriteLine("프로그램을 종료하려면 <EXIT> 을 입력하세요.");

            string inputCommand = string.Empty;

            while (true)
            {
                inputCommand = Console.ReadLine() ?? string.Empty;

                if (inputCommand.Equals("<EXIT>"))
                {
                    break;
                }

                byte[] buffSend = Encoding.ASCII.GetBytes(inputCommand);

                //(4)
                clientSocket.Send(buffSend);

                byte[] buffReceived = new byte[128];
                int nRecv = clientSocket.Receive(buffReceived);

                Console.WriteLine("서버로부터 수신한 데이터: {0}", Encoding.ASCII.GetString(buffReceived, 0, nRecv));
            }
        }
        // + 수정 Step 1.
        catch (SocketException se) when (se.SocketErrorCode == SocketError.ConnectionRefused)
        {
            Console.WriteLine("⚠️ 연결 거절: 해당 주소/포트에서 서버가 수신 중이 아닙니다.");
            Console.WriteLine("- 서버가 실행 중인지 확인");
        }
        catch (SocketException se)
        {
            Console.WriteLine($"소켓 예외: {se.SocketErrorCode} - {se.Message}");
        }
        catch (Exception ex)
        {
            Console.WriteLine($"예상치 못한 오류: {ex}");
        }
        finally
        {
            //(5)
            if (clientSocket != null)
            {
                if (clientSocket.Connected)
                    clientSocket.Shutdown(SocketShutdown.Both);

                clientSocket.Dispose();// Close() 생략 가능 (Dispose가 Close 포함)
            }

            //string stop = Console.ReadLine();
        }

        Console.WriteLine("아무 키나 누르면 프로그램이 종료됩니다...");
        Console.ReadKey();
    }
}