using System; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; namespace ChatServer.util { class NetUtil { public class StateObject { // size of receive buffer public const int BufferSize = 1024; // receive buffer public byte[] buffer = new byte[BufferSize]; // received data string public StringBuilder sb = new StringBuilder(); // client socket public Socket workSocket = null; public void ClearBuffer() { Array.Clear(buffer, 0, BufferSize); } } public static void StartListening() { IPEndPoint iep = new IPEndPoint(IPAddress.Parse("172.16.10.197"), 8888); Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); try { listener.Bind(iep); listener.Listen(20); Console.WriteLine("Waiting for a connection..."); while (true) { // 내부적으로 클라이언트 연결 요청을 수락하기 위한 루프를 돌리고 루프가 끝나는 것을 기다리는 것이 아닌 다음 코드 제어가 이동됨 listener.BeginAccept(new AsyncCallback(AcceptCallback), listener); } } catch (Exception e) { Console.WriteLine(e.ToString()); } } // 클라이언트 소켓을 얻고 비동기적으로 패킷을 receive하는 메서드 public static void AcceptCallback(IAsyncResult ar) { // Get the socket that handles the client request Socket listener = (Socket)ar.AsyncState; Socket clientSocket = listener.EndAccept(ar); IPEndPoint remoteIpEndPoint = clientSocket.RemoteEndPoint as IPEndPoint; Console.WriteLine("연결된 호스트:" + remoteIpEndPoint.Address + ":" + remoteIpEndPoint.Port); // Create the state object StateObject state = new StateObject(); state.workSocket = clientSocket; clientSocket.BeginReceive( state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state); } public static void ReadCallback(IAsyncResult ar) { // AsyncResult로 부터 AsyncState 객체(StateObject)를 찾고 얘로 부터 소켓을 얻는다 StateObject state = (StateObject) ar.AsyncState; Socket clientSocket = state.workSocket; try { QueueUtil.Enqueue(new Item(state)); if (clientSocket.Connected) { // buffer로 메시지를 받고 receive 함수로 메시지가 올 때까지 대기 clientSocket.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state); } } catch (Exception e) { Console.WriteLine("예외 발생..."); clientSocket.Shutdown(SocketShutdown.Both); clientSocket.Close(); } } } }