본문 바로가기
IT, 컴퓨터

[C#] 소켓 통신과 예제

by 별찌파파 2023. 11. 14.
728x90
반응형
SMALL
728x90

 

처음 프로그래밍을 접하게 된 후 가장 먼저 해보는 통신 중에 하나 소켓 통신일 것입니다. 보통 모든 개발언에서 가장 기본적으로 배우게 되고, 이 소켓 통신을 이용해서 채팅 프로그램이나 간단한 네트워크 게임 등의 응용프로그램을 만들어보기 시작할 것입니다. 저도 대학교 때는 소켓통신을 이용하여 App 간 통신을 하도록 하거나 H/W와의 메시지를 주고받아 구동하도록 하는 프로젝트도 진행했었습니다. 당시에는 C++로 진행했었습니다. 오늘은 소켓통신에 대해서 알아보고 간단하게 C#으로 예제를 구현해 보도록 하겠습니다.

 

소켓 통신(Socket Communication)은 컴퓨터 네트워크에서 프로세스 간에 데이터를 교환하기 위한 메커니즘입니다. 소켓은 컴퓨터 간에 통신을 담당하는 소프트웨어적인 장치로, 일반적으로 TCP/IP 프로토콜을 기반으로 합니다.

소켓 통신은 다음과 같은 주요 특징을 가지고 있습니다:

 

  1. 통신 방식:
    • TCP (Transmission Control Protocol): 연결 지향적인 통신 프로토콜로, 안정적인 데이터 전송을 보장합니다. 데이터의 손실이나 순서 변경이 거의 없으며, 신뢰성 있는 통신이 필요한 경우에 주로 사용됩니다.
    • UDP (User Datagram Protocol): 비연결성이며 신뢰성이 낮은 프로토콜로, 빠른 데이터 전송이 요구되는 경우에 사용됩니다. 일부 데이터의 손실이나 순서 변경이 허용됩니다.
  2. 서버와 클라이언트:
    • 서버(Server): 서비스를 제공하고, 클라이언트의 연결 요청을 받아들이며, 데이터를 주고받는 역할을 합니다.
    • 클라이언트(Client): 서버에 연결을 요청하고, 서버와 데이터를 주고받는 역할을 합니다.
  3. 포트 (Port): 소켓 통신에서는 포트를 사용하여 특정 프로세스와 연결됩니다. 서버 및 클라이언트는 서로 다른 포트를 사용하여 통신합니다.
  4. 소켓 타입:
    • 스트림 소켓(Stream Socket): 연결 지향적인 통신을 제공하며, 신뢰성 있는 데이터 스트림을 전송합니다. 주로 TCP 소켓이 이에 해당합니다.
    • 데이터그램 소켓(Datagram Socket): 비연결성 통신을 제공하며, UDP와 관련이 있습니다.
  5. 통신 프로세스:
    • 바인딩(Binding): 소켓을 특정 주소와 포트에 연결하는 과정입니다.
    • 리스닝(Listening): 서버 소켓이 클라이언트의 연결 요청을 수신 대기하는 상태입니다.
    • 연결(Connection): 클라이언트가 서버에 연결을 요청하고, 서버가 이를 수락하는 과정입니다.
    • 데이터 교환(Data Exchange): 서버와 클라이언트 간에 데이터를 주고받는 과정입니다.
    • 종료(Termination): 통신이 완료되면 소켓을 닫아 리소스를 해제합니다.

소켓 통신은 네트워크 프로그래밍에서 매우 중요한 부분이며, 웹 브라우저와 웹 서버 간의 통신에서부터 다양한 클라이언트-서버 응용프로그램까지 다양한 분야에서 사용됩니다. 프로그래밍 언어 및 플랫폼에 따라 소켓 통신을 지원하는 API가 다르지만, 대표적으로 C#, C/C++, Java, Python 등에서는 소켓 프로그래밍을 위한 API를 제공하고 있습니다.

반응형

아래는 서버 로컬 호스트의 8080번 포트에서 클라이언트의 연결을 기다리고, 클라이언트는 서버에 연결한 후 사용자로부터 메시지를 입력받아 서버로 전홍하고, 서버는 받은 메시지를 다시 클라이언트에게 돌려주는 간단한 코드입니다.

C# 서버 코드

 

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

class Server
{
    static void Main()
    {
        // 서버 소켓 생성
        TcpListener serverSocket = new TcpListener(IPAddress.Any, 8080);
        serverSocket.Start();
        Console.WriteLine("서버 시작. 대기 중...");

        // 클라이언트 연결 대기
        TcpClient clientSocket = serverSocket.AcceptTcpClient();
        Console.WriteLine("클라이언트 연결됨.");

        // 네트워크 스트림 생성
        NetworkStream networkStream = clientSocket.GetStream();

        byte[] bytesFrom = new byte[10025];
        string dataFromClient = null;

        while (true)
        {
            try
            {
                // 클라이언트로부터 데이터 읽기
                networkStream.Read(bytesFrom, 0, (int)clientSocket.ReceiveBufferSize);
                dataFromClient = Encoding.UTF8.GetString(bytesFrom);
                dataFromClient = dataFromClient.Substring(0, dataFromClient.IndexOf("$"));

                Console.WriteLine("클라이언트로부터 수신한 메시지: " + dataFromClient);

                // 클라이언트에게 데이터 전송
                string serverResponse = "서버에서 수신한 메시지: " + dataFromClient;
                Byte[] sendBytes = Encoding.UTF8.GetBytes(serverResponse);
                networkStream.Write(sendBytes, 0, sendBytes.Length);
                networkStream.Flush();

                Console.WriteLine("클라이언트에게 응답 전송: " + serverResponse);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }
    }
}
클라이언트 코드
using System;
using System.Net.Sockets;
using System.Text;

class Client
{
    static void Main()
    {
        try
        {
            TcpClient clientSocket = new TcpClient();
            clientSocket.Connect("127.0.0.1", 8080);

            Console.WriteLine("서버에 연결됨.");

            while (true)
            {
                Console.Write("메시지 입력: ");
                string clientMessage = Console.ReadLine();

                NetworkStream networkStream = clientSocket.GetStream();
                byte[] outStream = Encoding.UTF8.GetBytes(clientMessage + "$");
                networkStream.Write(outStream, 0, outStream.Length);
                networkStream.Flush();

                byte[] inStream = new byte[10025];
                networkStream.Read(inStream, 0, (int)clientSocket.ReceiveBufferSize);
                string serverResponse = Encoding.UTF8.GetString(inStream);
                serverResponse = serverResponse.Substring(0, serverResponse.IndexOf("$"));

                Console.WriteLine("서버로부터 수신한 응답: " + serverResponse);
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }
    }
}
728x90
반응형
LIST