NetUtil.cs 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. using System;
  2. using System.Net;
  3. using System.Net.Sockets;
  4. using System.Text;
  5. using System.Threading;
  6. namespace ChatServer.util
  7. {
  8. class NetUtil
  9. {
  10. public class StateObject
  11. {
  12. // size of receive buffer
  13. public const int BufferSize = 1024;
  14. // receive buffer
  15. public byte[] buffer = new byte[BufferSize];
  16. // received data string
  17. public StringBuilder sb = new StringBuilder();
  18. // client socket
  19. public Socket workSocket = null;
  20. public void ClearBuffer()
  21. {
  22. Array.Clear(buffer, 0, BufferSize);
  23. }
  24. }
  25. public static void StartListening()
  26. {
  27. IPEndPoint iep = new IPEndPoint(IPAddress.Parse("172.16.10.197"), 8888);
  28. Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  29. try
  30. {
  31. listener.Bind(iep);
  32. listener.Listen(20);
  33. Console.WriteLine("Waiting for a connection...");
  34. while (true)
  35. {
  36. // 내부적으로 클라이언트 연결 요청을 수락하기 위한 루프를 돌리고 루프가 끝나는 것을 기다리는 것이 아닌 다음 코드 제어가 이동됨
  37. listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
  38. }
  39. }
  40. catch (Exception e)
  41. {
  42. Console.WriteLine(e.ToString());
  43. }
  44. }
  45. // 클라이언트 소켓을 얻고 비동기적으로 패킷을 receive하는 메서드
  46. public static void AcceptCallback(IAsyncResult ar)
  47. {
  48. // Get the socket that handles the client request
  49. Socket listener = (Socket)ar.AsyncState;
  50. Socket clientSocket = listener.EndAccept(ar);
  51. IPEndPoint remoteIpEndPoint = clientSocket.RemoteEndPoint as IPEndPoint;
  52. Console.WriteLine("연결된 호스트:" + remoteIpEndPoint.Address + ":" + remoteIpEndPoint.Port);
  53. // Create the state object
  54. StateObject state = new StateObject();
  55. state.workSocket = clientSocket;
  56. clientSocket.BeginReceive(
  57. state.buffer, 0,
  58. StateObject.BufferSize, 0,
  59. new AsyncCallback(ReadCallback), state);
  60. }
  61. public static void ReadCallback(IAsyncResult ar)
  62. {
  63. // AsyncResult로 부터 AsyncState 객체(StateObject)를 찾고 얘로 부터 소켓을 얻는다
  64. StateObject state = (StateObject) ar.AsyncState;
  65. Socket clientSocket = state.workSocket;
  66. try
  67. {
  68. QueueUtil.Enqueue(new Item(state));
  69. if (clientSocket.Connected)
  70. {
  71. // buffer로 메시지를 받고 receive 함수로 메시지가 올 때까지 대기
  72. clientSocket.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReadCallback), state);
  73. }
  74. }
  75. catch (Exception e)
  76. {
  77. Console.WriteLine("예외 발생...");
  78. clientSocket.Shutdown(SocketShutdown.Both);
  79. clientSocket.Close();
  80. }
  81. }
  82. }
  83. }