📄 소켓 프로그래밍
지금까지 네트워크의 기본적인 이론을 다뤘다면, 이제부터 클라이언트와 서버 간 통신을 위한 프로그램을 작성해보도록 하겠습니다.
📑 Server
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace ServerCore
{
class Program
{
private static void Main(string[] args)
{
//DNS 사용
string host = Dns.GetHostName(); //현재 로컬의 호스트를 가져옴
IPHostEntry ipHost = Dns.GetHostEntry(host);
IPAddress ipAddress = ipHost.AddressList[0]; //배열로 들어있는 값 중에서 가장 첫번째 사용(임시)
IPEndPoint endPoint = new IPEndPoint(ipAddress, 7777); //엔드포인트(ip주소와 포트번호)
//리슨소켓 생성
//TCP 통신을 사용
Socket listenSocket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
try
{
//리슨소켓 설정
listenSocket.Bind(endPoint);
//최대 대기수
listenSocket.Listen(10);
while (true)
{
Console.WriteLine("Listening...");
//클라이언트와 연결
Socket clientSocket = listenSocket.Accept(); //다음 단계로 넘어갈 수 없으면 여기서 대기함 (블로킹)
//클라이언트로부터 수신
byte[] recieveBuffer = new byte[1024];
int recieveBytes = clientSocket.Receive(recieveBuffer); //recieveBuffer에 스트림을 넣고, 리턴값은 몇바이트를 받았는지 저장
string recieveData = Encoding.UTF8.GetString(recieveBuffer, 0, recieveBytes); //문자열로 획득
Console.WriteLine($"클라이언트로부터 받음: {recieveData}");
//클라이언트에게 송신
byte[] sendBuffer = Encoding.UTF8.GetBytes("Hello World From Server");
clientSocket.Send(sendBuffer);
//클라이언트 킥
clientSocket.Shutdown(SocketShutdown.Both); //미리 예고
clientSocket.Close(); //실질적으로 통신 해제
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
}
using System.Net;
using System.Net.Sockets;
using System.Text;
- 소켓을 사용하기 위한 System.Net과, 스트림을 인코딩, 디코딩 할 System.Text를 추가합니다.
string host = Dns.GetHostName(); //현재 로컬의 호스트를 가져옴
IPHostEntry ipHost = Dns.GetHostEntry(host);
IPAddress ipAddress = ipHost.AddressList[0]; //배열로 들어있는 값 중에서 가장 첫번째 사용(임시)
IPEndPoint endPoint = new IPEndPoint(ipAddress, 7777); //엔드포인트(ip주소와 포트번호)
- DNS를 사용하여 소켓통신을 구현합니다.
- 테스트를 위해 자신의 호스트이름을 가져옵니다. 그 중 첫번째 IP주소를 획득한 후(임시) 지정한 포트(7777, 임시)로 엔드포인트를 생성합니다.
Socket listenSocket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
- TCP 통신 프로토콜을 이용하는 소켓을 생성합니다.
//리슨소켓 설정
listenSocket.Bind(endPoint);
//최대 대기수
listenSocket.Listen(10);
생성한 소켓(리슨소켓)에 엔드포인트 정보를 넣어줍니다. (소켓 설정)
최대 대기수(backlog)는 10으로 지정하였습니다.(임시)
//클라이언트와 연결
Socket clientSocket = listenSocket.Accept(); //다음 단계로 넘어갈 수 없으면 여기서 대기함 (블로킹)
- 클라이언트로부터 연결 요청이 들어오면 실행됩니다.
- 연결 요청이 없는경우 이곳에서 대기합니다(블로킹)
//클라이언트로부터 수신
byte[] recieveBuffer = new byte[1024];
int recieveBytes = clientSocket.Receive(recieveBuffer); //recieveBuffer에 스트림을 넣고, 리턴값은 몇바이트를 받았는지 저장
string recieveData = Encoding.UTF8.GetString(recieveBuffer, 0, recieveBytes); //문자열로 획득
Console.WriteLine($"클라이언트로부터 받음: {recieveData}");
- 리시브 버퍼를 만들어 클라이언트 소켓으로부터 온 정보를 담습니다.
- 스트림을 String으로 변환하여 출력합니다.
//클라이언트에게 송신
byte[] sendBuffer = Encoding.UTF8.GetBytes("Hello World From Server");
clientSocket.Send(sendBuffer);
- 클라이언트에게 송신합니다.
📑 Client
using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace DummyClient
{
class Program
{
static void Main(string[] args)
{
//DNS 사용
string host = Dns.GetHostName(); //현재 로컬의 호스트를 가져옴
IPHostEntry ipHost = Dns.GetHostEntry(host);
IPAddress ipAddress = ipHost.AddressList[0];
IPEndPoint endPoint = new IPEndPoint(ipAddress, 7777);
//소켓 설정
Socket socket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
try
{
//연결 시도
socket.Connect(endPoint); //이곳에서 대기 (블로킹)
//연결 된 경우 진행
Console.WriteLine($"서버와 연결됨, {socket.RemoteEndPoint.ToString()}");
//서버에게 송신
byte[] sendBuffer = Encoding.UTF8.GetBytes("Hello World From Client");
int sendBytes = socket.Send(sendBuffer);
//서버로부터 수신
byte[] recieveBuffer = new byte[1024];
int recieveBytes = socket.Receive(recieveBuffer);
string recieveData = Encoding.UTF8.GetString(recieveBuffer, 0, recieveBytes);
Console.WriteLine($"서버로부터 수신: {recieveData}");
//연결 해제
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
}
//연결 시도
socket.Connect(endPoint); //이곳에서 대기 (블로킹)
- 동일한 방법으로 생성한 소켓(ip주소와 port가 동일)을 이용하여 연결을 시도합니다.
- 연결할때까지 이곳에서 대기합니다(블로킹)
'server > socket server' 카테고리의 다른 글
[C# 서버] Async Session, Event (0) | 2023.02.06 |
---|---|
[C# 서버] Async Listener (0) | 2023.01.17 |
[C# 서버] Thread Local Storage (0) | 2023.01.12 |
[C# 서버] ReaderWriterLock 구현 (0) | 2023.01.11 |
[C# 서버] ReaderWriterLock (0) | 2023.01.10 |