public async Task ServerMainAction() { while (stream == null) { await Task.Delay(200); } client.ReceiveTimeout = Timeout.Infinite; int bufferSize = 0; int messageSize = 0; Methods.DataKind currentKind = 0; int current = 0; byte[] headBuffer = new byte[4]; byte[] messageBuffer = new byte[1024]; CancellationToken cancelToken = Canceller.Token; while (true) { try { while (true) { bufferSize = await stream.ReadAsync(headBuffer, 0, 4, cancelToken); if (Canceller.IsCancellationRequested) { return; } if (bufferSize == 4) { messageSize = BitConverter.ToInt32(headBuffer, 0); // little endian current = 0; goto data_kind_read_start; } } data_kind_read_start: while (true) { bufferSize = await stream.ReadAsync(headBuffer, 0, 4, cancelToken); if (Canceller.IsCancellationRequested) { return; } if (bufferSize == 4) { currentKind = (Methods.DataKind)BitConverter.ToInt32(headBuffer, 0); // little endian goto message_read_start; } } message_read_start: byte[] currentBuffer = messageBuffer.Length < messageSize ? new byte[messageSize] : messageBuffer; while (current < messageSize) { bufferSize = await stream.ReadAsync(currentBuffer, current, messageSize, cancelToken); current += bufferSize; if (Canceller.IsCancellationRequested) { return; } } if (isClient) { switch (currentKind) { case Methods.DataKind.GameInit: clientReader.OnGameInit(MessagePackSerializer.Deserialize <Methods.GameInit>(currentBuffer)); break; case Methods.DataKind.TurnStart: clientReader.OnTurnStart(MessagePackSerializer.Deserialize <Methods.TurnStart>(currentBuffer)); break; case Methods.DataKind.TurnEnd: clientReader.OnTurnEnd(MessagePackSerializer.Deserialize <Methods.TurnEnd>(currentBuffer)); break; case Methods.DataKind.GameEnd: clientReader.OnGameEnd(MessagePackSerializer.Deserialize <Methods.GameEnd>(currentBuffer)); break; case Methods.DataKind.Pause: clientReader.OnPause(MessagePackSerializer.Deserialize <Methods.Pause>(currentBuffer)); break; case Methods.DataKind.Interrupt: clientReader.OnInterrupt(MessagePackSerializer.Deserialize <Methods.Interrupt>(currentBuffer)); break; case Methods.DataKind.RebaseByUser: clientReader.OnRebaseByUser(MessagePackSerializer.Deserialize <Methods.RebaseByUser>(currentBuffer)); break; default: throw new FormatException(); } } else { switch (currentKind) { case Methods.DataKind.Connect: var Data = MessagePackSerializer.Deserialize <Methods.Connect>(currentBuffer); AIProcess = Process.GetProcessById(Data.ProcessId); AIProcess.EnableRaisingEvents = true; AIProcess.Exited += __onAIProcessExited; serverReader.OnConnect(Data); break; case Methods.DataKind.Decided: serverReader.OnDecided(MessagePackSerializer.Deserialize <Methods.Decided>(currentBuffer)); break; case Methods.DataKind.DecidedEx: serverReader.OnDecidedEx(MessagePackSerializer.Deserialize <Methods.DecidedEx>(currentBuffer)); break; case Methods.DataKind.Interrupt: serverReader.OnInterrupt(MessagePackSerializer.Deserialize <Methods.Interrupt>(currentBuffer)); break; default: throw new FormatException(); } } } catch (Exception ex) { if (ex is TimeoutException) { continue; } if (ex is ObjectDisposedException) { return; } if (ex.InnerException is SocketException && ((SocketException)(ex.InnerException)).ErrorCode == 10060) { continue; } OnExceptionThrown?.Invoke(ex); if (ex is IOException) { return; } } } }