728x90
아래와 같이 Socket문법에서 Accept()는 블로킹 함수이다. 블로킹 함수란 무한정 대기한다는 뜻이다.
무수한 유저를 받기위해서는 블로킹 함수를 채택하는 것 은 바람직 하지 않을 수 있다.
결국 논블로킹 방법을 사용해야한다.
동기방식인 블로킹 문법 Accept()
Socket _listenSocket;
_listener.Accept()
비동기방식인 논블로킹 문법 AcceptAsync()
internal class Listener
{
Socket _listenSocket;
Action<Socket> _onAcceptHandler;
public void Init(IPEndPoint endPoint, Action<Socket> onAcceptHandler)
{
//문지기
_listenSocket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
_onAcceptHandler += onAcceptHandler;
//문지기교육
_listenSocket.Bind(endPoint);
//영업시작
//backlog : 최대 대기수
_listenSocket.Listen(10);
SocketAsyncEventArgs args = new SocketAsyncEventArgs();
args.Completed += new EventHandler<SocketAsyncEventArgs>(OnAcceptCompleted);
RegisterAccept(args);
}
void RegisterAccept(SocketAsyncEventArgs args)
{
args.AcceptSocket = null;
bool pending = _listenSocket.AcceptAsync(args);
if (pending == false)
OnAcceptCompleted(null, args);
}
void OnAcceptCompleted(object sender, SocketAsyncEventArgs args)
{
if (args.SocketError == SocketError.Success)
{
_onAcceptHandler.Invoke(args.AcceptSocket);
}
else
Console.WriteLine(args.SocketError.ToString());
RegisterAccept(args);
}
}
Main
static Listener _listener = new Listener();
static void Main(string[] arg)
{
//DNS (Domain Name System) -> www.xxxxx.com
string host = Dns.GetHostName();
IPHostEntry ipHost = Dns.GetHostEntry(host);
IPAddress ipAddr = ipHost.AddressList[0];
IPEndPoint endPoint = new IPEndPoint(ipAddr, 7777);
_listener.Init(endPoint, OnAcceptHandler);
Console.WriteLine("Listen...");
while (true)
{ ; }
}
static void OnAcceptHandler(Socket clientSocket)
{
try
{
//받는다.
byte[] recvBuff = new byte[1024];
int recvBytes = clientSocket.Receive(recvBuff);//몇개의 리시브 바이트를 받았는지
string recvData = Encoding.UTF8.GetString(recvBuff, 0, recvBytes);
Console.WriteLine($"FromClient : {recvData}");
//보낸다.
byte[] sendBuff = Encoding.UTF8.GetBytes("Welcom");
clientSocket.Send(sendBuff);
//클라이언트 제거
clientSocket.Shutdown(SocketShutdown.Both);//클라이언트에게 끊을 예정이란걸 알려줌
clientSocket.Close();
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
728x90
'VisualStudio > C#서버' 카테고리의 다른 글
[C#서버][방법] BitConverter 사용법 - ArraySegment<byte>, Span, Slice (0) | 2022.10.31 |
---|---|
[C#서버] TCP VS UDP (0) | 2022.10.27 |
[C#서버][소스] 기본 서버, 클라이언트 소스 (0) | 2022.10.27 |
[C#서버] TLS(Thread Local Storage) - 쓰레드로컬(ThreadLocal) (0) | 2022.10.26 |
[C#서버][개념] 임계영역 특수락 - ReaderWriterLockSlim 특수상황 Lock 처리 방법 (0) | 2022.10.26 |