728x90
반응형
서버 - 클라이언트 프로그래밍에서 소켓 프로그래밍은
서버와 클라이언트 모두 연결을 위한 대리자, 즉 소켓을 이용하여 서로 연결하는 프로그래밍입니다.
이때 서버와 클라이언트의 진행 방식에 있어서 서로 차이점이 존재합니다.
1) 클라이언트 단계의 소켓 프로그래밍
클라이언트는 소켓을 준비하여 서버 주소로 Connect를 요청할 수 있습니다.
그리고 Connect 요청이 받아들여진 후
서버 소켓을 통해 Session 소켓과 패킷을 서로 송신/수신할 수 있습니다.
2) 서버 단계의 소켓 프로그래밍
서버는 클라이언트와 다르게 소켓 프로그래밍을 위한 준비 절차가 조금 복잡합니다.
그 절차를 간단하게 다음과 같이 표현할 수 있습니다.
- 클라이언트로부터 접속 요청(=Connect)을 받는 Listener 소켓 준비
- 준비된 Listener 소켓에 대해 Bind(서버의 주소/Port를 소켓에 연동)
- 접속 요청(=Connect)을 받기 위해 Listen 상태에 돌입
- Listen 상태에서 접속 요청(=Connect)이 들어오면 Accept
위와 같은 절차로 서버에서는 소켓 프로그래밍이 동작하게 됩니다.
그리고 서버에서는 클라이언트 소켓을 통해 클라이언트와 Session 소켓과 패킷을 서로 송/수신합니다.
그렇다면 이제 실제 코드를 통해 클라이언트-서버간의 소켓 프로그래밍을 구현해보겠습니다.
1) Server 코드
static void Main(string[] args)
{
// DNS를 사용
string host = Dns.GetHostName();
IPHostEntry ipHost = Dns.GetHostEntry(host);
IPAddress ipAddr = ipHost.AddressList[0];
IPEndPoint endPoint = new IPEndPoint(ipAddr, 7777);
// Server의 ClientSocket을 TCP로 동작하게끔 설정
Socket listenSocket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
try
{
// ClientSocket에 대해 bind
listenSocket.Bind(endPoint);
// Listen 상태 설정 - 최대 대기수
listenSocket.Listen(10);
while (true)
{
Console.WriteLine("Listening...");
// Client로부터 Connect가 들어오는 경우, ClientSocket으로 Accept함
Socket ClientSocket = listenSocket.Accept();
// Client로부터 받은 내용을 기록
byte[] recvBuffer = new byte[1024];
int recvBytes = ClientSocket.Receive(recvBuffer);
string recvData = Encoding.UTF8.GetString(recvBuffer, 0, recvBytes);
Console.WriteLine($"From Client : {recvData}");
// Client로 전달
byte[] sendBuffer = Encoding.UTF8.GetBytes("Welcome to Server!!!");
ClientSocket.Send(sendBuffer);
// Client와의 연결 중지 - 우선 Client의 ServerSocket 연결 중지
ClientSocket.Shutdown(SocketShutdown.Both);
ClientSocket.Close();
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
2) Client 코드
static void Main(string[] args)
{
// DNS를 사용
string host = Dns.GetHostName();
IPHostEntry ipHost = Dns.GetHostEntry(host);
IPAddress ipAddr = ipHost.AddressList[0];
IPEndPoint endPoint = new IPEndPoint(ipAddr, 7777);
// Server Socket 설정
Socket socket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
try
{
// Server에게 Connect 요청
socket.Connect(endPoint);
Console.WriteLine($"Connected to {socket.RemoteEndPoint.ToString()}");
// 서버로 전송
byte[] sendBuffer = Encoding.UTF8.GetBytes("Hello From Client");
int sendBytes = socket.Send(sendBuffer);
// 서버로부터 받음
byte[] recvBuffer = new byte[1024];
int recvBytes = socket.Receive(recvBuffer);
string recvData = Encoding.UTF8.GetString(recvBuffer, 0, recvBytes);
Console.WriteLine($"From Server : {recvData}");
// Server 소켓 종료
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
이제 두 코드를 빌드하여 실제 실행결과를 확인해보겠습니다.
문제없이 동작하여
Client는 연결을 수행한 후 종료되었고,
Server는 무한 반복문을 실행하여 동작중인 것을 확인할 수 있습니다.
728x90
반응형
'C#' 카테고리의 다른 글
Session_1 (0) | 2024.12.24 |
---|---|
Listener (0) | 2024.12.18 |
네트워크 기초 + 통신 모델 (0) | 2024.12.11 |
Thread Local Storage (0) | 2024.12.09 |
ReaderWriterLock 구현 (0) | 2024.12.09 |