// ServerCore
// Main.cs
class Program
{
static Listner _listener = new Listner();
static void OnAcceptHandler(Socket clientSocket)
{
try
{
/*
Main에서 데이터를 받는 부분을 Session으로 빼보자
*/
// 받는 부분
byte[] recvBuff = new byte[1024];
int recvBytes = clientSocket.Receive(recvBuff);
string recvData = Encoding.UTF8.GetString(recvBuff, 0/*시작인덱스*/, recvBytes/*문자열이 몇개인가*/);
Console.WriteLine($"[From Client] {recvData}");
// 보내는 부분
byte[] sendBuff = Encoding.UTF8.GetBytes("Welcom to MMORPG Server ");
clientSocket.Send(sendBuff);
// 소켓을 닫는다
clientSocket.Shutdown(SocketShutdown.Both); /*소켓을 닫는다를 미리 공지*/
clientSocket.Close(); /*실제로 닫는 부분*/
}
catch(Exception e)
{
}
}
static void Main(string[] args)
{
// DNS(Domain Name System)을 사용할 예정
// ip addr를 안쓰고 도메인네임을 쓰겠다는 말.
string host = Dns.GetHostName();
IPHostEntry ipHost = Dns.GetHostEntry(host);
IPAddress ipAddr = ipHost.AddressList[0];
IPEndPoint endPoint = new IPEndPoint(ipAddr, 7777/* Port */);
_listener.Init(endPoint, OnAcceptHandler);
while(true)
{
}
}
}
// ServerCore
// Session.cs
class Session
{
Socket _socket;
public void Start(Socket socket)
{
_socket = socket;
SocketAsyncEventArgs recvArgs = new SocketAsyncEventArgs();
recvArgs.Completed += new EventHandler<SocketAsyncEventArgs>(OnRecvComplete);
recvArgs.SetBuffer(new byte[1024], 0/*시작인덱스*/, 1024);
RegisterRecv(recvArgs);
}
public void Send(byte[] sendBuff)
{
_socket.Send(sendBuff);
}
public void Disconnect()
{
_socket.Shutdown(SocketShutdown.Both);
_socket.Close();
}
void RegisterRecv(SocketAsyncEventArgs args)
{
bool pending = _socket.ReceiveAsync(args);
if(pending == false)
OnRecvComplete(null, args);
}
void OnRecvComplete(object sender, SocketAsyncEventArgs args)
{
if(args.BytesTransferred > 0 && args.SocketError ==SocketError.Success)
{
try{
string recvData = Encoding.UTF8.GetString(args.Buffer, args.Offset, args.BytesTransferred);
RegisterRecv(args);
}
catch()
{
}
}
else
{
// Disconnect
}
}
}
// ServerCore
// Main.cs
class Program
{
static Listner _listener = new Listner();
static void OnAcceptHandler(Socket clientSocket)
{
try
{
Session session = new Session();
session.Start(clientSocket);
byte[] sendBuff = Encoding.UTF8.GetBytes("Welcom to MMORPG Server ");
session.Send(sendBuff);
Thread.Sleep(1000);
session.Disconnect();
}
catch(Exception e)
{
}
}
static void Main(string[] args)
{
// DNS(Domain Name System)을 사용할 예정
// ip addr를 안쓰고 도메인네임을 쓰겠다는 말.
string host = Dns.GetHostName();
IPHostEntry ipHost = Dns.GetHostEntry(host);
IPAddress ipAddr = ipHost.AddressList[0];
IPEndPoint endPoint = new IPEndPoint(ipAddr, 7777/* Port */);
_listener.Init(endPoint, OnAcceptHandler);
while(true)
{
}
}
}
한 가지 안전하지 못한 부분이 있다
public void Disconnect()
{
/*
멀티쓰레드 환경에서
Disconnect가 두 번 발생할 경우 에러가 발생
*/
_socket.Shutdown(SocketShutdown.Both);
_socket.Close();
}
// ServerCore
// Session.cs
class Session
{
Socket _socket;
int _disconnected = 0;
// ...
public void Disconnect()
{
if(Interlocked.Exchange(ref _disconnected, 1) == 1)
return;
_socket.Shutdown(SocketShutdown.Both);
_socket.Close();
}