TcpListener/ TcpClient 클래스 (클라이언트 구현)

00·2025년 1월 6일

C#

목록 보기
128/149
using System;
using System.Diagnostics; // 현재 프로세스 정보를 가져오기 위한 네임스페이스
using System.Net; // 네트워크 관련 클래스를 사용하기 위한 네임스페이스
using System.Net.Sockets; // 소켓 통신을 위한 네임스페이스
using System.Text; // 문자열 인코딩을 위한 네임스페이스


/*
주의:
직전 깃에 있는 [TcpListener/ TcpClient 클래스 (서버 구현)]에서 만든 EchoSetver 커맨드 창을 먼저 띄우고,
다른 창에서 아래 코드로 완성한 EchoClient 커맨드 창을 띄워서 테스트해야 합니다.
 */


// TcpListener/ TcpClient 클래스를 활용한 '메아리 클라이언트 구현'하기
// 클라이언트가 보낸 메시지를 서버가 그대로 돌려보내는 프로그램
namespace EchoClient
{
    class MainApp
    {
        static void Main(string[] args)
        {
            if (args.Length < 4) // 필요한 명령줄 인수가 제공되지 않으면 사용법을 출력하고 프로그램 종료
            {
                Console.WriteLine(
                    "사용법 : {0} <Bind IP> <Bind Port> <Server IP> <Message>",
                    Process.GetCurrentProcess().ProcessName);
                return;
            }

            string bindIp = args[0]; // 클라이언트가 바인딩할 IP 주소
            int bindPort = Convert.ToInt32(args[1]); // 클라이언트가 바인딩할 포트 번호
            string serverIp = args[2]; // 서버의 IP 주소
            const int serverPort = 5425; // 서버의 포트 번호
            string message = args[3]; // 서버에 보낼 메시지

            try
            {
                // 클라이언트와 서버의 IP 주소와 포트 번호를 사용하여 IPEndPoint 객체를 생성합니다.
                IPEndPoint clientAddress = new IPEndPoint(IPAddress.Parse(bindIp), bindPort);
                IPEndPoint serverAddress = new IPEndPoint(IPAddress.Parse(serverIp), serverPort);

                Console.WriteLine("클라이언트: {0}, 서버:{1}", clientAddress.ToString(), serverAddress.ToString()); // 클라이언트와 서버의 정보를 출력합니다.

                TcpClient client = new TcpClient(clientAddress); // TcpClient 객체를 생성하고 클라이언트 주소로 초기화합니다.

                client.Connect(serverAddress); // 서버에 연결합니다.

                byte[] data = System.Text.Encoding.Default.GetBytes(message); // 메시지를 바이트 배열로 변환합니다.

                NetworkStream stream = client.GetStream(); // 네트워크 스트림을 가져옵니다.

                stream.Write(data, 0, data.Length); // 스트림에 데이터를 씁니다.

                Console.WriteLine("송신: {0}", message); // 송신 메시지를 출력합니다.

                data = new byte[256]; // 수신 데이터를 저장할 바이트 배열을 생성합니다.

                string responseData = ""; // 수신 데이터를 저장할 문자열 변수를 선언합니다.

                int bytes = stream.Read(data, 0, data.Length); // 스트림에서 데이터를 읽습니다.
                responseData = Encoding.Default.GetString(data, 0, bytes); // 읽은 데이터를 문자열로 변환합니다.
                Console.WriteLine("수신: {0}", responseData); // 수신 메시지를 출력합니다.

                stream.Close(); // 스트림을 닫습니다.
                client.Close(); // 클라이언트를 닫습니다.
            }
            catch (SocketException e) // 소켓 예외 발생 시 처리
            {
                Console.WriteLine(e); // 예외 정보를 출력합니다.
            }

            Console.WriteLine("클라이언트를 종료합니다."); // 클라이언트 종료 메시지를 출력합니다.
        }
    }
}

코드 설명

using System;
using System.Diagnostics; // 현재 프로세스 정보를 가져오기 위한 네임스페이스
using System.Net; // 네트워크 관련 클래스를 사용하기 위한 네임스페이스
using System.Net.Sockets; // 소켓 통신을 위한 네임스페이스
using System.Text; // 문자열 인코딩을 위한 네임스페이스

namespace EchoClient
{
    class MainApp
    {
        static void Main(string[] args)
        {
            if (args.Length < 4) // 필요한 명령줄 인수가 제공되지 않으면 사용법을 출력하고 프로그램 종료
            {
                Console.WriteLine(
                    "사용법 : {0} <Bind IP> <Bind Port> <Server IP> <Message>",
                    Process.GetCurrentProcess().ProcessName);
                return;
            }

            string bindIp = args[0]; // 클라이언트가 바인딩할 IP 주소
            int bindPort = Convert.ToInt32(args[1]); // 클라이언트가 바인딩할 포트 번호
            string serverIp = args[2]; // 서버의 IP 주소
            const int serverPort = 5425; // 서버의 포트 번호
            string message = args[3]; // 서버에 보낼 메시지

            try
            {
                // 클라이언트와 서버의 IP 주소와 포트 번호를 사용하여 IPEndPoint 객체를 생성합니다.
                IPEndPoint clientAddress = new IPEndPoint(IPAddress.Parse(bindIp), bindPort);
                IPEndPoint serverAddress = new IPEndPoint(IPAddress.Parse(serverIp), serverPort);

                Console.WriteLine("클라이언트: {0}, 서버:{1}", clientAddress.ToString(), serverAddress.ToString()); // 클라이언트와 서버의 정보를 출력합니다.

                TcpClient client = new TcpClient(clientAddress); // TcpClient 객체를 생성하고 클라이언트 주소로 초기화합니다.

                client.Connect(serverAddress); // 서버에 연결합니다.

                byte[] data = System.Text.Encoding.Default.GetBytes(message); // 메시지를 바이트 배열로 변환합니다.

                NetworkStream stream = client.GetStream(); // 네트워크 스트림을 가져옵니다.

                stream.Write(data, 0, data.Length); // 스트림에 데이터를 씁니다.

                Console.WriteLine("송신: {0}", message); // 송신 메시지를 출력합니다.

                data = new byte[256]; // 수신 데이터를 저장할 바이트 배열을 생성합니다.

                string responseData = ""; // 수신 데이터를 저장할 문자열 변수를 선언합니다.

                int bytes = stream.Read(data, 0, data.Length); // 스트림에서 데이터를 읽습니다.
                responseData = Encoding.Default.GetString(data, 0, bytes); // 읽은 데이터를 문자열로 변환합니다.
                Console.WriteLine("수신: {0}", responseData); // 수신 메시지를 출력합니다.

                stream.Close(); // 스트림을 닫습니다.
                client.Close(); // 클라이언트를 닫습니다.
            }
            catch (SocketException e) // 소켓 예외 발생 시 처리
            {
                Console.WriteLine(e); // 예외 정보를 출력합니다.
            }

            Console.WriteLine("클라이언트를 종료합니다."); // 클라이언트 종료 메시지를 출력합니다.
        }
    }
}

코드 설명

이 C# 코드는 TCP 소켓을 사용하여 에코 서버에 메시지를 보내고 응답을 받는 에코 클라이언트를 구현한 예제입니다.

  • Process.GetCurrentProcess().ProcessName: 현재 실행 중인 프로세스의 이름을 가져옵니다.
  • string bindIp = args[0];, int bindPort = Convert.ToInt32(args[1]);, string serverIp = args[2];, string message = args[3];: 명령줄 인수에서 클라이언트 IP 주소, 클라이언트 포트 번호, 서버 IP 주소, 메시지를 가져옵니다.
  • IPEndPoint clientAddress = new IPEndPoint(IPAddress.Parse(bindIp), bindPort);, IPEndPoint serverAddress = new IPEndPoint(IPAddress.Parse(serverIp), serverPort);: 클라이언트와 서버의 IP 주소와 포트 번호를 사용하여 IPEndPoint 객체를 생성합니다.
  • TcpClient client = new TcpClient(clientAddress);: TcpClient 객체를 생성하고 클라이언트 주소로 초기화합니다.
  • client.Connect(serverAddress);: 서버에 연결합니다.
  • byte[] data = System.Text.Encoding.Default.GetBytes(message);: 메시지를 바이트 배열로 변환합니다.
  • NetworkStream stream = client.GetStream();: 네트워크 스트림을 가져옵니다.
  • stream.Write(data, 0, data.Length);: 스트림에 데이터를 씁니다.
  • Console.WriteLine("송신: {0}", message);: 송신 메시지를 출력합니다.
  • data = new byte[256];: 수신 데이터를 저장할 바이트 배열을 생성합니다.
  • int bytes = stream.Read(data, 0, data.Length);: 스트림에서 데이터를 읽습니다.
  • responseData = Encoding.Default.GetString(data, 0, bytes);: 읽은 데이터를 문자열로 변환합니다.
  • Console.WriteLine("수신: {0}", responseData);: 수신 메시지를 출력합니다.
  • stream.Close();: 스트림을 닫습니다.
  • client.Close();: 클라이언트를 닫습니다.
  • catch (SocketException e): 소켓 예외 발생 시 처리합니다.

이 코드는 TCP 소켓 통신을 사용하여 서버에 메시지를 전송하고 응답을 받는 방법을 보여줍니다.


TcpListenerTcpClient 클래스

TcpListenerTcpClient 클래스는 TCP 소켓 통신을 위한 클래스입니다.

TcpListener는 서버에서 클라이언트의 연결 요청을 수신 대기하는 데 사용되고, TcpClient는 클라이언트에서 서버에 연결하는 데 사용됩니다.

이 코드에서는 TcpClient 클래스를 사용하여 에코 서버에 연결하고 메시지를 주고받는 에코 클라이언트를 구현했습니다. 따라서 "TCP 소켓 통신을 사용하여 에코 클라이언트를 만들었습니다"


TCP 소켓 통신

TCP 소켓 통신은 인터넷에서 데이터를 주고받는 방식 중 하나입니다.

소켓은 데이터를 주고받는 창구라고 생각하면 됩니다.

TCP데이터를 안정적으로 전송하기 위한 규칙입니다.

TCP 소켓 통신은 클라이언트와 서버 사이에서 이루어지는데,

  • 클라이언트는 서비스를 요청하는 쪽이고 (예: 웹 브라우저)
  • 서버는 서비스를 제공하는 쪽입니다 (예: 웹 서버).

TCP 소켓 통신 과정

  1. 연결 요청: 클라이언트가 서버에 연결을 요청합니다.
  2. 연결 수락: 서버가 클라이언트의 연결 요청을 수락합니다.
  3. 데이터 송수신: 클라이언트와 서버가 연결된 소켓을 통해 데이터를 주고받습니다.
  4. 연결 종료: 클라이언트 또는 서버가 연결을 종료합니다.

TCP 소켓 통신의 특징

  • 연결 지향: 클라이언트와 서버가 연결된 후에 데이터를 주고받습니다.
  • 신뢰성: 데이터 손실이나 순서 오류 없이 안정적으로 데이터를 전송합니다.
  • 양방향: 클라이언트와 서버가 동시에 데이터를 주고받을 수 있습니다.

TCP 소켓 통신의 예

  • 웹 브라우징: 웹 브라우저는 TCP 소켓 통신을 사용하여 웹 서버에 웹 페이지를 요청하고, 웹 서버는 웹 페이지 데이터를 브라우저에 전송합니다.
  • 파일 전송: FTP(File Transfer Protocol)는 TCP 소켓 통신을 사용하여 파일을 전송합니다.
  • 이메일: SMTP(Simple Mail Transfer Protocol)는 TCP 소켓 통신을 사용하여 이메일을 전송합니다.

TCP 소켓 통신은 인터넷에서 다양한 서비스를 제공하는 데 사용되는 중요한 기술입니다.

TCP 소켓 통신 = TCP 네트워크 프로그래밍?

TCP 소켓 통신과 TCP 네트워크 프로그래밍은 엄밀히 말하면 같은 의미는 아니지만, 서로 밀접하게 관련되어 있어서 많은 경우 혼용되어 사용됩니다.

TCP 소켓 통신은 TCP 프로토콜을 사용하는 소켓 프로그래밍의 한 유형입니다. 즉, TCP 소켓 통신은 TCP 네트워크 프로그래밍의 하위 개념이라고 볼 수 있습니다.

TCP 네트워크 프로그래밍은 TCP 프로토콜을 사용하여 네트워크 상에서 데이터를 주고받는 프로그램을 개발하는 것을 의미합니다. TCP 소켓 통신 외에도 HTTP, FTP, SMTP 등 다양한 TCP 기반 프로토콜을 사용하여 네트워크 프로그래밍을 할 수 있습니다.

TCP 소켓 통신은 TCP 네트워크 프로그래밍의 한 방법으로, 소켓을 사용하여 클라이언트와 서버 간에 연결을 설정하고 데이터를 주고받습니다.

요약하자면,

  • TCP 네트워크 프로그래밍은 TCP 프로토콜을 사용하는 모든 네트워크 프로그래밍을 의미합니다.
  • TCP 소켓 통신은 소켓을 사용하는 TCP 네트워크 프로그래밍의 한 유형입니다.

따라서 TCP 소켓 통신은 TCP 네트워크 프로그래밍의 일부라고 할 수 있으며, 둘 사이에는 포함 관계가 성립합니다.

0개의 댓글