Socket Communication은 컴퓨터 네트워크에서 두 프로세스 간에 데이터를 주고받기 위한 엔드포인트를 제공하는 메커니즘입니다. Socket은 IP 주소와 포트 번호를 결합하여 하나의 네트워크에서 두 장치가 서로 통신할 수 있게 합니다.
Socket Communication이란?
개요
Socket 통신은 네트워크 프로그래밍의 핵심 요소로, 클라이언트-서버 모델에서 주로 사용됩니다.
클라이언트는 서버에 연결을 요청하고, 서버는 클라이언트의 요청을 받아들이거나 거부할 수 있습니다.
이 연결을 통해 데이터를 주고받는 것이 Socket 통신의 기본 원리입니다.
OSI 7 Layer 모델
Socket 통신은 네트워크 프로그래밍의 핵심 요소로, 컴퓨터 네트워크 상에서 두 프로세스가 데이터를 주고받기 위한 엔드포인트를 제공합니다.
이를 이해하기 위해 OSI(Open Systems Interconnection) 7 Layer 모델을 통해 더 자세히 알아보겠습니다.
OSI 7 Layer 모델은 네트워크 통신을 일곱 개의 계층으로 나누어 설명하는 모델입니다. 각 계층은 특정한 네트워크 기능을 담당하며, 서로 독립적으로 설계되었습니다.
- 물리 계층 (Physical Layer): 데이터 전송을 위한 물리적인 매체를 정의합니다. 예를 들어, 케이블, 라우터 등의 하드웨어가 포함됩니다.
- 데이터 링크 계층 (Data Link Layer): 물리 계층을 통해 데이터를 전송하고 오류 검출 및 수정 기능을 제공합니다. 예를 들어, 이더넷, 스위치가 포함됩니다.
- 네트워크 계층 (Network Layer): 데이터를 목적지까지 경로 설정 및 전송합니다. IP 주소를 이용한 라우팅 기능을 담당합니다.
- 전송 계층 (Transport Layer): 데이터 전송의 신뢰성을 보장합니다. TCP, UDP 프로토콜이 이 계층에 속합니다.
- 세션 계층 (Session Layer): 통신 세션을 설정, 유지 및 종료합니다.
- 표현 계층 (Presentation Layer): 데이터 형식 변환, 압축, 암호화 등의 기능을 제공합니다.
- 응용 계층 (Application Layer): 사용자와 직접 상호작용하는 애플리케이션을 제공합니다. HTTP, FTP, SMTP 등이 이 계층에 속합니다.

Protocol 종류
Protocol 종류로 일반적으로 TCP/IP와 UDP를 선택하여 사용합니다. 이는 보통 속도와 신뢰성을 위한 부분에서 필요에 따라 선택적으로 사용합니다.
1. TCP (Transmission Control Protocol)
- 특징:
- 연결 지향적 프로토콜로, 신뢰성 있는 데이터 전송을 보장합니다.
- 데이터는 순서대로 전송되며, 손실된 데이터는 재전송됩니다.
- 장점:
- 데이터 무결성을 보장하며, 흐름 제어와 혼잡 제어 기능을 제공합니다.
- 패킷이 순서대로 도착합니다.
- 단점:
- 연결 설정과 해제 과정에서 오버헤드가 발생하며, 데이터 전송 속도가 상대적으로 느립니다.
- 사용 예:
- 웹 브라우징(HTTP/HTTPS), 이메일(SMTP, IMAP, POP3), 파일 전송(FTP)
2. UDP (User Datagram Protocol)
- 특징:
- 비연결 지향적 프로토콜로, 빠르고 간단한 데이터 전송을 제공합니다.
- 데이터그램은 독립적으로 전송됩니다.
- 장점:
- 연결 설정이 필요 없고, 오버헤드가 적으며 빠른 데이터 전송이 가능합니다.
- 브로드캐스트와 멀티캐스트를 지원합니다.
- 단점:
- 데이터 전송의 신뢰성을 보장하지 않으며, 데이터 순서 보장이 없습니다.
- 데이터 손실이 발생할 수 있습니다.
- 사용 예:
- 실시간 스트리밍, 온라인 게임, VoIP(Voice over IP)
3. ICMP (Internet Control Message Protocol)
- 특징:
- 네트워크 상태 및 오류 메시지를 전달하는 데 사용되는 프로토콜입니다.
- 주로 네트워크 진단 및 관리 용도로 사용됩니다.
- 장점:
- 네트워크 문제를 탐지하고 진단하는 데 유용합니다.
- 패킷 손실 및 지연을 분석할 수 있습니다.
- 단점:
- 데이터 전송을 목적으로 하지 않으며, 주로 네트워크 상태 정보를 전달하는 데 사용됩니다.
- 사용 예:
- 핑(Ping), 트레이서트(Traceroute)
4. SCTP (Stream Control Transmission Protocol)
- 특징:
- 연결 지향적 프로토콜로, 다중 스트림과 다중 호밍 기능을 지원합니다.
- TCP와 UDP의 장점을 결합한 프로토콜입니다.
- 장점:
- 다중 스트림을 통해 데이터가 병렬로 전송되며, 하나의 연결에 여러 IP 주소를 사용할 수 있습니다.
- 데이터 순서 보장과 신뢰성 있는 전송을 제공합니다.
- 단점:
- 복잡성이 높으며, 모든 네트워크 환경에서 지원되지 않을 수 있습니다.
- 사용 예:
- 전송 제어 프로토콜, 통신 네트워크(VoIP 등)
C#에서 Socket 통신 사용하기
주요 네임스페이스(NameSpace)
- System.Net: 네트워킹 기능을 제공하는 네임스페이스입니다. IP 주소와 같은 네트워크 정보를 다룹니다.
- System.Net.Sockets: 소켓을 이용한 네트워크 통신 기능을 제공하는 네임스페이스입니다.
주요 클래스(Class)
- IPAddress: IP 주소를 나타내는 클래스입니다.
- Parse(string ipString): 문자열 형식의 IP 주소를 IPAddress 객체로 변환합니다.
- IPEndPoint: 네트워크 엔드포인트를 나타내는 클래스입니다. IP 주소와 포트 번호를 결합하여 생성됩니다.
- IPEndPoint(IPAddress address, int port): IP 주소와 포트를 사용하여 IPEndPoint 인스턴스를 초기화합니다.
- Socket: 소켓을 생성하고 관리하는 클래스입니다. 클라이언트와 서버 간의 연결을 설정하고 데이터를 송수신할 수 있습니다.
- Socket(AddressFamily addressFamily, SocketType socketType, ProtocolType protocolType): 소켓을 초기화합니다.
- Bind(EndPoint localEP): 소켓을 로컬 엔드포인트에 바인딩합니다.
- Listen(int backlog): 들어오는 연결을 대기 상태로 만듭니다.
- Accept(): 대기 중인 연결을 수락합니다.
- Connect(EndPoint remoteEP): 원격 호스트에 연결을 시도합니다.
- Send(byte[] buffer): 데이터를 송신합니다.
- Receive(byte[] buffer): 데이터를 수신합니다.
- Shutdown(SocketShutdown how): 소켓의 송수신을 중지합니다.
- Close(): 소켓을 닫습니다.
- Encoding: 문자열을 바이트 배열로 변환하거나 바이트 배열을 문자열로 변환하는 데 사용됩니다.
- ASCII: ASCII 인코딩을 사용합니다.
- GetBytes(string s): 문자열을 바이트 배열로 변환합니다.
- GetString(byte[] bytes, int index, int count): 바이트 배열을 문자열로 변환합니다.
Socket 종류
1. 스트림 소켓 (Stream Socket)
- 특징: 연결 지향적(연결 기반) 소켓으로, TCP(Transmission Control Protocol)를 사용합니다. 데이터를 신뢰성 있게 전송하고 수신합니다.
- 장점: 데이터가 순서대로 전달되고, 데이터 손실이 거의 없습니다. 연결 상태를 유지하기 때문에 안정적인 통신이 가능합니다.
- 단점: 연결 설정과 해제에 추가적인 오버헤드가 발생합니다.
- 사용 예: 웹 브라우징, 이메일 전송, 파일 전송 등
2. 데이터그램 소켓 (Datagram Socket)
- 특징: 비연결 지향적(비연결 기반) 소켓으로, UDP(User Datagram Protocol)를 사용합니다. 데이터를 독립적인 패킷으로 전송합니다.
- 장점: 연결 설정 없이 데이터를 전송할 수 있어 빠릅니다. 오버헤드가 적고, 브로드캐스트와 멀티캐스트에 적합합니다.
- 단점: 데이터가 순서대로 도착하지 않을 수 있으며, 데이터 손실이 발생할 수 있습니다.
- 사용 예: 실시간 스트리밍, 온라인 게임, VoIP(Voice over IP) 등
3. 원시 소켓 (Raw Socket)
- 특징: IP 계층의 헤더 정보를 직접 다룰 수 있는 소켓으로, TCP나 UDP와 같은 전송 계층 프로토콜을 직접 다룰 수 있습니다.
- 장점: 네트워크 프로토콜의 모든 세부 정보를 제어할 수 있습니다. 맞춤형 프로토콜을 구현하거나 네트워크 패킷을 분석할 때 유용합니다.
- 단점: 프로그래밍이 복잡하며, 잘못된 구현은 네트워크에 문제를 일으킬 수 있습니다. 일반적으로 관리자 권한이 필요합니다.
- 사용 예: 네트워크 모니터링, 침입 탐지 시스템, 네트워크 프로토콜 분석 등
기본 동작 순서
- 서버 소켓을 설정하고 클라이언트 연결을 기다립니다. (
Bind
,Listen
) - 클라이언트가 서버에 연결을 시도합니다. (
Connect
) - 클라이언트와 서버 간에 데이터를 주고받습니다. (
Send
,Receive
) - 연결을 종료합니다. (
Shutdown
,Close
)

예제
예제는 TCP/IP를 사용한 예제를 작성하였습니다.
Socket Server
using System; using System.Net; using System.Net.Sockets; using System.Text; namespace SocketServer { class Program { static void Main() { // Set the IP address and port IPAddress ipAddress = IPAddress.Parse("127.0.0.1"); int port = 8080; IPEndPoint localEndPoint = new IPEndPoint(ipAddress, port); // Create a TCP/IP socket Socket listener = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp); try { // Bind the socket to the local endpoint and listen for incoming connections listener.Bind(localEndPoint); listener.Listen(10); // 10 is the maximum length of the pending connections queue Console.WriteLine("Start Server. Waiting for a connection..."); // Accept the connection Socket handler = listener.Accept(); string data = null; byte[] bytes = new byte[1024]; // Data buffer // Receive the data int bytesRec = handler.Receive(bytes); // The number of bytes received data += Encoding.ASCII.GetString(bytes, 0, bytesRec); // Convert bytes to string Console.WriteLine("Receive Data: {0}", data); // Send response to the client byte[] msg = Encoding.ASCII.GetBytes("Received your message."); handler.Send(msg); handler.Shutdown(SocketShutdown.Both); handler.Close(); } catch (Exception e) { Console.WriteLine(e.ToString()); } Console.WriteLine("Close the server."); } } }
Socket Client
using System; using System.Net.Sockets; using System.Net; using System.Text; namespace HelloWorld { class Program { static void Main() { // Set the IP address and port IPAddress ipAddress = IPAddress.Parse("127.0.0.1"); int port = 8080; IPEndPoint remoteEP = new IPEndPoint(ipAddress, port); // Create a TCP/IP socket Socket sender = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp); try { // Try to connect to the server sender.Connect(remoteEP); Console.WriteLine("Successfully connected to {0}", sender.RemoteEndPoint); // Send message to the server string message = "Hello Server!"; byte[] msg = Encoding.ASCII.GetBytes(message); int bytesSent = sender.Send(msg); // Receive response from the server byte[] bytes = new byte[1024]; int bytesRec = sender.Receive(bytes); Console.WriteLine("Res receive: {0}", Encoding.ASCII.GetString(bytes, 0, bytesRec)); sender.Shutdown(SocketShutdown.Both); sender.Close(); // Wait Console.ReadKey(); } catch (Exception e) { Console.WriteLine(e.ToString()); } Console.WriteLine("Close the client."); } } }
결과

참고 링크
- My Git Repository (devitworld-csharp-basic) – DevitworldConsoleApp/9_3_SocketServer
- My Git Repository (devitworld-csharp-basic) – DevitworldConsoleApp/9_3_SocketClient