123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- 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();
- }
- }
- }
- }
|