/// <summary> /// 送信タスクを開始する。 /// </summary> public void StartSendingTask() { lock (_SyncSendingTask) { // 開始済みなら、そのまま抜ける if (_SendingTaskEnable) { return; } _SendingTaskEnable = true; _SendingTask = new Task(async() => { int errorCount = -1; ReStart: try { ++errorCount; CommunicationEventArgs args = new CommunicationEventArgs(this); Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); long lastTime = stopwatch.ElapsedMilliseconds; while (_SendingTaskEnable) { // 送信処理の実行 OnDataSending(args); // 周期実行のためのディレイ if (SendingCycle >= 0) { int delayTime = SendingCycle - (int)(stopwatch.ElapsedMilliseconds - lastTime); if (delayTime < 0) { delayTime = SendingCycle; } await Task.Delay(delayTime); } errorCount = 0; // 終了時の時間 lastTime = stopwatch.ElapsedMilliseconds; } } catch (Exception ex) { if (errorCount < MaxTaskErrorCount) { goto ReStart; } else { // イベント発生 OnErrorOccurred(new CommunicationErrorEventArgs(this, ex)); // 切断 Disconnect(); } } }); _SendingTask.Start(); } }
/// <summary> /// 送信スレッドの送信タイミングのときのアクション。 /// </summary> /// <param name="e">イベント引数。</param> protected virtual void OnDataSending(CommunicationEventArgs e) { if (DataSending != null) { DataSending(this, e); } }
/// <summary> /// 切断開始時のアクション。 /// </summary> /// <param name="e">イベント引数。</param> protected virtual void OnDisconnecting(CommunicationEventArgs e) { if (Disconnecting != null) { Disconnecting(this, e); } }
/// <summary> /// ClientAccepted イベントを発生させる。 /// </summary> /// <param name="e">イベント引数。</param> protected virtual void OnClientAccepted(CommunicationEventArgs e) { if (ClientAccepted != null) { ClientAccepted(this, e); } }
/// <summary> /// ClientDisconnected イベントを発生させる。 /// </summary> /// <param name="e">イベント引数。</param> protected virtual void OnClientDisconnected(CommunicationEventArgs e) { if (this.ClientDisconnected != null) { this.ClientDisconnected(this, e); } }
/// <summary> /// 接続完了時のアクション。 /// </summary> /// <param name="e">イベント引数。</param> protected virtual void OnConnected(CommunicationEventArgs e) { _ErrorFlag = false; if (Connected != null) { Connected(this, e); } }
/// <summary> /// クライアントから切断されたときに実行されるイベントハンドラ。 /// </summary> /// <param name="sender">イベント発生元。</param> /// <param name="e">イベント引数。</param> private void Client_Disconnecting(object sender, CommunicationEventArgs e) { // リストから削除する TCPCommunication communication = (TCPCommunication)sender; if (_AcceptedClients.Contains(communication)) { _AcceptedClients.Remove(communication); } // イベントを発生させる OnClientDisconnected(new CommunicationEventArgs(communication)); }
/// <summary> /// BeginAcceptのコールバック。 /// </summary> /// <param name="ar">非同期操作のステータスを表します。</param> private void AcceptCallback(IAsyncResult ar) { // 接続要求を受け入れる Socket soc = null; try { lock (_SyncSocket) { soc = _Socket.EndAccept(ar); } } catch { // サーバを閉じる CloseServer(); return; } // TCPCommunicationの作成 TCPCommunication client = new TCPCommunication(soc); // 最大数を超えていないか if (_AcceptedClients.Count >= MaxClients) { client.Disconnect(); client.Dispose(); } else { // コレクションに追加 _AcceptedClients.Add(client); // イベントハンドラの追加 client.Disconnecting += Client_Disconnecting; client.DataReceived += Client_DataReceived; client.ErrorOccurred += Client_ErrorOccurred; // 受信タスクを起動 client.StartReceivingTask(); // イベントを発生 CommunicationEventArgs args = new CommunicationEventArgs(client); OnClientAccepted(args); } // 接続要求施行を再開する _Socket.BeginAccept(new AsyncCallback(this.AcceptCallback), null); }