Socket 서버
Socket 서버
Socket 클래스는 클라이언트와 서버에서 공히 사용할 수 있는데, 여기서는 Socket 서버를 구현하는 부분에 대해 알아본다.
아래 예제는 TCP 클라이언트에서 받은 메시지를 그대로 돌려보내는 소켓 서버 프로그램이다.
개념 설명에 포커스하기 위해 일단 이 소켓 서버는 하나의 클라이언트만 동기적으로 핸들링하도록 작성하였다.
이 프로그램은 임의의 키를 누를 때까지 계속 된다.
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace socksrv
{
class Program
{
static void Main(string[] args)
{
// (1) 소켓 객체 생성 (TCP 소켓)
Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
// (2) 포트에 바인드
IPEndPoint ep = new IPEndPoint(IPAddress.Any, 7000);
sock.Bind(ep);
// (3) 포트 Listening 시작
sock.Listen(10);
// (4) 연결을 받아들여 새 소켓 생성 (하나의 연결만 받아들임)
Socket clientSock = sock.Accept();
byte[] buff = new byte[8192];
while (!Console.KeyAvailable) // 키 누르면 종료
{
// (5) 소켓 수신
int n = clientSock.Receive(buff);
string data = Encoding.UTF8.GetString(buff, 0, n);
Console.WriteLine(data);
// (6) 소켓 송신
clientSock.Send(buff, 0, n, SocketFlags.None); // echo
}
// (7) 소켓 닫기
clientSock.Close();
sock.Close();
}
}
}
위 예제를 각 스텝별로 살펴보면,
-
먼저 서버 Socket 객체를 생성하는데, 이는 Socket 클라이언트에서 Socket 객체를 생성하는 것과 동일하다.
-
서버는 포트를 열고 클라이언트 접속을 기다리는데, 먼저 어떤 포트를 사용할지 바인드해 주게 된다.
-
서버에서 포트를 열고 클라이언트 접속을 실제 기다리기 위해 Socket 객체의 Listen() 메서드를 사용한다.
Listen() 메서드는 동시에 여러 클라이언트가 접속되었을 때 큐에 몇 개의 클라이언트가 대기할 수 있는지 지정할 수 있는데,
위의 경우는 예시를 위해 10을 넣었다.
-
Socket 객체의 Accept() 메서드를 사용하여 클라이언트 접속을 받아들이고 새 소켓 객체를 리턴한다. 이후, 클라이언트는
이 새로 생성된 소켓 객체와 통신하게 된다. 일반적으로 소켓 서버는 이 Accept 이전에 무한 루프를 만드는데, 여기서는 하나의
클라이언트만 처리하도록 이를 생략하였다.
-
소켓에서 데이타를 수신하기 위해 Socket 객체의 Receive() 메서드를 사용하였다.
이는 소켓 클라이언트에서 수신하는 것과 동일하다.
참고로 while 루프에서 Console.KeyAvailable 를 체크하였는데, 이는 키보드가 눌려졌는지를 체크하는 것으로
만약 키가 눌려지지 않았으면 Block하지 않고 계속 루프를 돌 수 있게 한다.
-
소켓에서 데이타를 전달하기 위해 Socket 객체의 Send() 메서드를 사용하였다.
이는 소켓 클라이언트에서 송신하는 것과 동일하다.
-
마지막으로 소켓을 닫는다.