C#에서 네트워크 통신을 구현하려면 System.Net.Sockets 네임스페이스를 사용합니다. 이 네임스페이스는 Windows Sockets 인터페이스(윈속, Winsock)의 관리형(managed) 구현체를 제공하여, 개발자가 복잡한 저수준 API를 직접 다루지 않고도 안정적인 네트워크 애플리케이션을 작성할 수 있게 해줍니다.
동기식과 비동기식 소켓
C# 소켓 프로그래밍에는 두 가지 기본 동작 모드가 있습니다.
- 동기식(Synchronous): 작업이 완료될 때까지 현재 스레드가 차단(blocking)됩니다. 코드 작성이 간단하지만, 대기 시간 동안 스레드가 멈추기 때문에 UI 애플리케이션이나 고성능 서버에는 적합하지 않을 수 있습니다.
- 비동기식(Asynchronous): 작업 완료 여부와 관계없이 즉시 제어권을 반환합니다. 콜백, async/await 패턴 등과 함께 사용하면 많은 클라이언트를 효율적으로 처리하는 서버를 만들 수 있습니다.
TcpListener를 이용한 기본 예제
다음은 System.Net.Sockets.TcpListener 클래스를 사용해 클라이언트 연결을 수락하고 네트워크 스트림을 생성하는 기본 예제입니다.
TcpListener l = new TcpListener(1234);
l.Start();
// 소켓 생성
Socket s = l.AcceptSocket();
Stream network = new NetworkStream(s);
위 코드의 흐름을 살펴보면 다음과 같습니다.
TcpListener(1234): 포트 1234에서 클라이언트 접속을 대기하는 리스너를 생성합니다.l.Start(): 리스너가 들어오는 연결 요청을 받기 시작합니다.AcceptSocket(): 클라이언트 연결을 수락하고 통신에 사용할Socket객체를 반환합니다. 이 메서드는 연결이 수립될 때까지 대기(차단)합니다.NetworkStream(s): 소켓 위에 데이터 읽기/쓰기용 스트림을 생성하여 손쉬운 입출력 처리를 가능하게 합니다.
TCP/IP 통신용 Socket 객체 생성하기
직접 Socket 클래스를 인스턴스화하여 TCP/IP 네트워크상에서 통신할 수도 있습니다.
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
생성자 매개변수 설명
- AddressFamily: 소켓 클래스가 네트워크 주소를 해석할 때 사용하는 표준 주소 체계입니다. IPv4는
AddressFamily.InterNetwork, IPv6는AddressFamily.InterNetworkV6를 사용합니다. - SocketType: 소켓의 유형입니다. 신뢰성 있는 양방향 연결 지향 통신에는
SocketType.Stream이 사용됩니다. - ProtocolType: 소켓에서 사용할 네트워크 프로토콜로, TCP는
ProtocolType.Tcp, UDP는ProtocolType.Udp를 지정합니다.
프로토콜 조합 정리
| 조합 | 특징 | 적합한 용도 |
|---|---|---|
| Stream + Tcp | 연결 지향, 데이터 순서 보장, 신뢰성 높음 | 파일 전송, 웹 서버, 채팅 |
| Dgram + Udp | 비연결 지향, 빠르지만 데이터 손실 가능 | 실시간 스트리밍, 게임, DNS 조회 |
마무리
C#의 System.Net.Sockets 네임스페이스는 Windows Sockets의 강력한 관리형 래퍼로, 동기식과 비동기식 두 가지 방식으로 네트워크 통신을 구현할 수 있습니다. 간단한 클라이언트-서버 애플리케이션부터는 TcpListener와 TcpClient로 시작하고, 더 세밀한 제어가 필요하다면 Socket 클래스를 직접 사용하면 됩니다. 실무에서는 비동기(async/await) 방식을 활용해 성능과 반응성을 모두 확보하는 것이 권장됩니다.