fork download
  1.  
  2. namespace Tcplib.Server
  3. {
  4. using System;
  5. using System.Net.Sockets;
  6. using System.Threading.Tasks;
  7.  
  8. /// <summary>
  9. /// Вспомогательный класс содержащий в себе информацию о текущей сессии
  10. /// </summary>
  11. public class Session
  12. {
  13. private const int defaultBufferSize = 1024;
  14. private byte[] _readBuffer;
  15. private byte[] _writeBuffer;
  16. private readonly TcpServer _owner;
  17. private TcpClient _client;
  18.  
  19. public Guid Guid { get; }
  20.  
  21. public Session(TcpServer owner, TcpClient client, Guid guid, int readBudderSize = 1024, int writeBufferSize = 1024)
  22. {
  23. _owner = owner;
  24. _client = client;
  25. Guid = guid;
  26. if (readBudderSize <= 0)
  27. readBudderSize = defaultBufferSize;
  28. if (writeBufferSize <= 0)
  29. writeBufferSize = defaultBufferSize;
  30. _readBuffer = new byte[readBudderSize];
  31. _writeBuffer = new byte[writeBufferSize];
  32. }
  33.  
  34. /// <summary>
  35. /// Метод получения датаграммы от клиента
  36. /// </summary>
  37. /// <param name="retryCount"></param>
  38. /// <param name="retryDelayMS"></param>
  39. /// <returns></returns>
  40. public async Task<ReadOnlyMemory<byte>?> TryReceiveData(int retryCount = 5, int retryDelayMS = 1000)
  41. {
  42. int readed = 0;
  43. try
  44. {
  45. var ns = _client.GetStream();
  46. do
  47. {
  48. readed += await ns.ReadAsync(_readBuffer.AsMemory().Slice(readed));
  49. if (_client.Client.Available == 0 || readed >= _readBuffer.Length)//мы прочитали все данные или в буффере уже нет места
  50. break;
  51. } while (ns.DataAvailable || retryCount > 0);
  52. }
  53. catch (SocketException ex)
  54. {
  55. Console.WriteLine("[WARN] SocketException in TryReceiveData");
  56. Console.WriteLine(ex.ToString());
  57. }
  58. catch (ObjectDisposedException ex)
  59. {
  60. Console.WriteLine("[WARN] ObjectDisposedException in TryReceiveData");
  61. Console.WriteLine(ex.ToString());
  62. }
  63. catch (Exception ex)
  64. {
  65. Console.WriteLine("[WARN] UndefinedException in TryReceiveData");
  66. Console.WriteLine(ex.ToString());
  67. }
  68. return _readBuffer[0..readed];
  69. }
  70.  
  71. /// <summary>
  72. /// ИИетод отправки датаграммы клиенту
  73. /// </summary>
  74. /// <param name="dataToSend"></param>
  75. /// <param name="retryCount"></param>
  76. /// <param name="retryDelayMS"></param>
  77. /// <returns></returns>
  78. public async Task TrySendData(ReadOnlyMemory<byte> datagramm, int retryCount = 5, int retryDelayMS = 1000)
  79. {
  80. try
  81. {
  82.  
  83. var ns = _client.GetStream();
  84. do
  85. {
  86. try
  87. {
  88. await ns.WriteAsync(datagramm);
  89. retryCount = 0;
  90. }
  91. catch (SocketException ex)
  92. {
  93. Console.WriteLine("[WARN] SocketException in TrySendData");
  94. Console.WriteLine(ex.ToString());
  95. }
  96. catch (ObjectDisposedException ex)
  97. {
  98. Console.WriteLine("[WARN] ObjectDisposedException in TrySendData");
  99. Console.WriteLine(ex.ToString());
  100. }
  101. catch (Exception ex)
  102. {
  103. Console.WriteLine("[WARN] UndefinedException in TrySendData");
  104. Console.WriteLine(ex.ToString());
  105. }
  106. retryCount--;
  107. await Task.Delay(retryCount);
  108. } while (retryCount > 0);
  109. }
  110. catch (SocketException ex)
  111. {
  112. Console.WriteLine("[WARN] SocketException in TrySendData");
  113. Console.WriteLine(ex.ToString());
  114. }
  115. catch (ObjectDisposedException ex)
  116. {
  117. Console.WriteLine("[WARN] ObjectDisposedException in TrySendData");
  118. Console.WriteLine(ex.ToString());
  119. }
  120. catch (Exception ex)
  121. {
  122. Console.WriteLine("[WARN] UndefinedException in TrySendData");
  123. Console.WriteLine(ex.ToString());
  124. }
  125. }
  126. public void StopSession()
  127. {
  128. try
  129. {
  130. _client.Close();
  131. _client.Dispose();
  132. }
  133. catch (SocketException ex)
  134. {
  135. Console.WriteLine("[WARN] SocketException in StopSession");
  136. Console.WriteLine(ex.ToString());
  137. }
  138. catch (ObjectDisposedException ex)
  139. {
  140. Console.WriteLine("[WARN] ObjectDisposedException in StopSession");
  141. Console.WriteLine(ex.ToString());
  142. }
  143. catch (Exception ex)
  144. {
  145. Console.WriteLine("[WARN] UndefinedException in StopSession");
  146. Console.WriteLine(ex.ToString());
  147. }
  148. }
  149. }
  150. }
  151.  
  152. namespace Tcplib.Server
  153. {
  154. using System.Net.Sockets;
  155. using System.Threading;
  156. using System.Collections.Concurrent;
  157. using System;
  158. using System.Threading.Tasks;
  159.  
  160. public class TcpServer
  161. {
  162. #region Events
  163. public event ServerStartedHandler ServerStarted;
  164. public event ServerStopedHandler ServerStoped;
  165. public event ClientConnectedHandler ClientAccepted;
  166. public event ClientDisconnectedHandler ClientDisconnected;
  167.  
  168. #endregion Events
  169.  
  170. #region ServerSettings
  171. private readonly ServerConfig _config;
  172.  
  173. #endregion ServerSettings
  174.  
  175. #region ServerFields
  176. private readonly TcpListener _listener;
  177. private readonly CancellationTokenSource _cancellationTokenSource;
  178. private readonly int _maxConnections;
  179. private readonly ConcurrentDictionary<Guid, Session> _sessions = new ConcurrentDictionary<Guid, Session>();
  180. #endregion
  181.  
  182. #region ServerProperties
  183. public bool IsStarted { get; private set; }
  184. #endregion ServerProperties
  185. public TcpServer(ServerConfig config)
  186. {
  187. _config = config;
  188. _listener = new TcpListener(_config.ListeningEndPoint);
  189. _maxConnections = _config.MaxConnections;
  190. _cancellationTokenSource = new CancellationTokenSource();
  191. }
  192. #region Server public methods
  193. public async void Start()
  194. {
  195. if(IsStarted)
  196. return;
  197. try{
  198. var token = _cancellationTokenSource.Token;
  199. _listener.Start();
  200. IsStarted = true;
  201. await Task.Run(() => AcceptCients(token));
  202. }
  203. catch(Exception ex)
  204. {
  205. Console.WriteLine("[WARN] UndefinedException in Start");
  206. Console.WriteLine(ex.ToString());
  207. }
  208.  
  209. }
  210. public void Stop()
  211. {
  212. if(!IsStarted)
  213. return;
  214. try
  215. {
  216. _listener.Stop();
  217. foreach(var c in _sessions.Values)
  218. {
  219. try{
  220. c.StopSession();
  221. }
  222. catch(Exception ex)
  223. {
  224. Console.WriteLine("[WARN] UndefinedException in Start");
  225. Console.WriteLine(ex.ToString());
  226. }
  227. }
  228. _sessions.Clear();
  229. }
  230. catch (SocketException ex)
  231. {
  232. Console.WriteLine("[WARN] SocketException in Stop");
  233. Console.WriteLine(ex.ToString());
  234. }
  235. catch (ObjectDisposedException ex)
  236. {
  237. Console.WriteLine("[WARN] ObjectDisposedException in Stop");
  238. Console.WriteLine(ex.ToString());
  239. }
  240. catch (Exception ex)
  241. {
  242. Console.WriteLine("[WARN] UndefinedException in Stop");
  243. Console.WriteLine(ex.ToString());
  244. }
  245. }
  246.  
  247. #endregion
  248.  
  249. #region Server private methods
  250.  
  251. private async Task AcceptCients(CancellationToken cancellationToken){
  252. try{
  253. while (IsStarted && !cancellationToken.IsCancellationRequested)
  254. {
  255. var acceptedClient = await _listener.AcceptTcpClientAsync();
  256. Guid clientGuid = Guid.NewGuid();
  257. var session = new Session(this, acceptedClient,clientGuid);
  258. if(!_sessions.TryAdd(clientGuid, session))
  259. {
  260. session.StopSession();
  261. continue;
  262. }
  263. ProcessSession(session);
  264. }
  265.  
  266. }
  267. catch (SocketException ex)
  268. {
  269. Console.WriteLine("[WARN] SocketException in Stop");
  270. Console.WriteLine(ex.ToString());
  271. }
  272. catch (ObjectDisposedException ex)
  273. {
  274. Console.WriteLine("[WARN] ObjectDisposedException in Stop");
  275. Console.WriteLine(ex.ToString());
  276. }
  277. catch (Exception ex)
  278. {
  279. Console.WriteLine("[WARN] UndefinedException in Stop");
  280. Console.WriteLine(ex.ToString());
  281. }
  282.  
  283. }
  284.  
  285. public Action<Session> ProcessSessionHandler;
  286.  
  287. private async void ProcessSession(Session session)
  288. {
  289. if(ProcessSessionHandler==null)
  290. return;
  291. await Task.Run(()=> ProcessSessionHandler(session));
  292. try
  293. {
  294. session.StopSession();
  295. }
  296. catch(Exception ex)
  297. {
  298. Console.WriteLine("[WARN] UndefinedException in ProcessSession");
  299. }
  300. if(!_sessions.TryRemove(session.Guid, out var s))
  301. {
  302. Console.WriteLine($"Cant remove session {session.Guid}");
  303. }
  304. }
  305.  
  306. #endregion Server private methods
  307.  
  308. }
  309. }
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.cs(68,33): error CS1001: Unexpected symbol `.', expecting identifier
prog.cs(68,40): error CS1001: Unexpected symbol `]', expecting identifier
Compilation failed: 2 error(s), 0 warnings
stdout
Standard output is empty