private void Receive(Socket client) { try { var state = new StateObjectModel <Socket> { WorkSocket = client, TimeoutChecker = new TimeoutChecker <Socket>( new TimeoutCheckerModel <Socket> { Target = client, OnTimeoutAction = Close, Logger = Logger, TimeoutTime = TimeoutTime }) }; client.BeginReceive(state.Buffer, 0, StateObjectModel <Socket> .DataInfoSize, 0, ReadTotalLengthCallback, state); } catch (Exception e) { Logger?.Log(new LogModel { Time = DateTime.Now, Message = $"資料接收失敗啦, 物件名稱 : {ToString( )}, 例外訊息 : {e.Message}" }); throw new InvalidOperationException($@"客戶端接收伺服器訊息失敗,詳細請參照 Inner Exception。 Inner Execption 訊息 : {e.Message}", e); } }
private void AcceptCallback(IAsyncResult asyncResult) { _allDone.Set( ); if (asyncResult.AsyncState is Socket listener) { try { var handler = listener.EndAccept(asyncResult); var state = new StateObjectModel <Socket> { WorkSocket = handler }; Logger?.Log(new LogModel { Time = DateTime.Now, Message = $"伺服器已接受用戶連線, 伺服器 : {handler.LocalEndPoint}, 用戶端 : {handler.RemoteEndPoint}" }); handler.BeginReceive(state.Buffer, 0, StateObjectModel <Socket> .DataInfoSize, 0, ReadTotalLengthCallback, state); } catch (ObjectDisposedException e) { Logger?.Log(new LogModel { Time = DateTime.Now, Message = $"伺服器已關閉, 伺服器:{LocalIpEndPoint}, 物件名稱 : {ToString( )}, 例外訊息 : {e.Message}" }); } } }
/// <summary> /// AsyncCallback method /// </summary> /// <param name="ar"></param> public void AcceptCallback(IAsyncResult ar) { // Signal the main thread to continue. mre.Set(); if (isListening == false) { return; } StateObjectModel state = new StateObjectModel(); try { lock (clients) { state.Id = !clients.Any() ? 1 : clients.Keys.Max() + 1; clients.Add(state.Id, state); logMessage.Message = $"Client with Id {state.Id} connected!"; _eventAggregator.PublishOnUIThread(logMessage); socketServerModel.NoClientsConnected = clients.Count(); UpdateUI(); } state.listener = (Socket)ar.AsyncState; state.listener = state.listener.EndAccept(ar); state.listener.BeginReceive(state.buffer, 0, StateObjectModel.BufferSize, 0, new AsyncCallback(ReadCallback), state); } catch (SocketException ex) { Debug.WriteLine(ex.Message); } }
/// <summary> /// Close the socket connection @ ID /// </summary> /// <param name="id"></param> public void Close(int id) { StateObjectModel state = GetClient(id); if (state == null) { Debug.WriteLine("Client does not exist."); } else { try { state.listener.Shutdown(SocketShutdown.Both); state.listener.Close(); } catch (SocketException) { // TODO: } finally { lock (clients) { clients.Remove(state.Id); Console.WriteLine("Client disconnected with Id {0}", state.Id); } } } }
/// <summary> /// ReadCallback method /// </summary> /// <param name="ar"></param> public void ReadCallback(IAsyncResult ar) { try { String content = String.Empty; // Retrieve the state object and the handler socket // from the asynchronous state object. StateObjectModel state = (StateObjectModel)ar.AsyncState; if (state.listener.Connected == false) { return; } Socket handler = state.listener; // Read data from the client socket. int bytesRead = handler.EndReceive(ar); //int id = ar.AsyncState.Id as StateObject; if (bytesRead > 0) { // There might be more data, so store the data received so far. state.sb.Append(Encoding.ASCII.GetString( state.buffer, 0, bytesRead)); // Check for end-of-file tag. If it is not there, read // more data. content = state.sb.ToString(); Debug.WriteLine($"Client {state.Id} is sending {content}"); var resultString = Regex.Match(content, @"\d+").Value; if (resultString != "") { // Update the UI thread socketServerModel.FocusTargetIndex = Int32.Parse(resultString); UpdateUI(); } // Not all data received. Get more. handler.BeginReceive(state.buffer, 0, StateObjectModel.BufferSize, 0, new AsyncCallback(ReadCallback), state); // Empty the string buffer state.sb.Clear(); } } catch (SocketException ex) { Debug.WriteLine(ex.Message); } }
private void TryReceiveCommandModel(Socket handler, StateObjectModel <Socket> state) { var totalBufferSize = BitConverter.ToInt32(state.Buffer, 0); state.Buffer = new byte[totalBufferSize]; try { handler.BeginReceive(state.Buffer, 0, totalBufferSize, SocketFlags.None, ReceiveCommandModelCallback, state); } catch (Exception e) { Logger?.Log(new LogModel { Time = DateTime.Now, Message = $"嘗試接收資料模型失敗, 物件名稱 : {ToString( )}, 例外訊息 : {e.Message}" }); } }
/// <summary> /// Gets the command model. /// </summary> /// <param name="state">The state.</param> /// <returns></returns> internal TCommandModel GetCommandModel(StateObjectModel <Socket> state) { var commandModel = default(TCommandModel); try { commandModel = IgnoreFormatter ? state.Buffer as TCommandModel : CommandFormatter.Deserialize(Compressor.Decompress(state.Buffer)); } catch (Exception e) { Logger?.Log(new LogModel { Time = DateTime.Now, Message = $"反序列化失敗囉, 物件名稱 : {ToString( )}, 例外訊息 : {e.Message}" }); } return(commandModel); }
/// <summary> /// Gets the Client state object @ ID /// </summary> /// <param name="id"></param> /// <returns></returns> private StateObjectModel GetClient(int id) { StateObjectModel state = new StateObjectModel(); return(clients.TryGetValue(id, out state) ? state : null); }