/// <summary> /// Connect /// </summary> /// <param name="sender"></param> /// <param name="e"></param> protected override void ButtonF1_Click(object sender, EventArgs e) { Logger.WriteLine(MethodBase.GetCurrentMethod().Name); base.ButtonF1_Click(sender, e); // ▼▼▼ 業務処理 ▼▼▼ if (TcpClientUtil != null) { // 既に接続している場合、再接続前に破棄する TcpClientUtil.Dispose(); } // 接続 string ip = tboxIP.Text; int.TryParse(tboxPort.Text, out int port); try { TcpClientUtil = new TcpClientManager(ip, port); listViewLog.Items.Add($"接続しました。{TcpClientUtil.GetClientIpAndPort()}->{TcpClientUtil.GetServerIpAndPort()}"); // 名前を送信 string name = tboxName.Text; TcpMessageUtility mgr = new TcpMessageUtility(TcpMessageUtility.HeaderConnect, name, TcpMessageUtility.TargetAll, name); TcpClientUtil.Send(mgr.GetSendMessage()); } catch (SocketException ex) { Debug.WriteLine(ex.ToString()); listViewLog.Items.Add(ex.Message); return; } // 読み込みループ開始 // Task停止用のトークン発行 ReadCancelTokenSource = new CancellationTokenSource(); CancellationToken cToken = ReadCancelTokenSource.Token; readLoopTask = ReadLoop(cToken); readLoopTask.ConfigureAwait(false); // ボタンの有効無効を設定 SetControlEnabled(ActionMode.Connect); // ▲▲▲ 業務処理 ▲▲▲ }
private async Task AcceptLoop(CancellationToken cToken) { Logger.StartMethod(nameof(AcceptLoop)); try { while (!cToken.IsCancellationRequested) { // Acceptを非同期待機 TcpServerManager.ClientInfo mgr = await TcpServerUtil.AcceptAsync().ConfigureAwait(false); // Accept完了後、後続処理が動く string acceptClientName = mgr.GetClientIpAndPort(); Invoke((Action)(() => { listViewLog.Items.Add($"[{MethodBase.GetCurrentMethod().Name}]{acceptClientName}が接続しました。"); })); // Read Loop Start mgr.ReadTask = ReadLoop(mgr, cToken); // 接続してきたクライアントに対し、既に接続している他のクライアントの情報を送信 foreach (string clientName in dicTcpClient.Keys) { TcpMessageUtility sendMsgMgr = new TcpMessageUtility(TcpMessageUtility.HeaderName, clientName, acceptClientName, clientName); TcpServerUtil.SendTarget(mgr.GetClientIpAndPort(), sendMsgMgr.GetSendMessage()); } } } catch (Exception ex) { Debug.WriteLine(ex.ToString()); Logger.WriteException(nameof(AcceptLoop), ex); } Logger.EndMethod(nameof(AcceptLoop)); }
private async Task ReadLoop(TcpServerManager.ClientInfo tcpClientMgr, CancellationToken cToken) { Logger.StartMethod(nameof(ReadLoop)); try { TcpClient client = tcpClientMgr.Client; while (!cToken.IsCancellationRequested) { // メッセージ受信 string texts = await TcpServerUtil.ReadAsync(client, cToken).ConfigureAwait(false); if (texts != null) { // \nで分割 foreach (string text in texts.Split('\n')) { Logger.WriteLine(text); Invoke((Action)(() => { listViewLog.Items.Add($"[Read]{text}"); })); TcpMessageUtility recvMsgMgr = new TcpMessageUtility(text); TcpMessageUtility sendMsgMgr; switch (recvMsgMgr.Header) { case TcpMessageUtility.HeaderConnect: // 名前設定 // 辞書のキーの変更 dicTcpClient.Remove(tcpClientMgr.GetClientIpAndPort()); if (!dicTcpClient.ContainsKey(recvMsgMgr.Value)) { // 受信した名前が未登録の場合 tcpClientMgr.Name = recvMsgMgr.Value; dicTcpClient.Add(tcpClientMgr.Name, tcpClientMgr); } else { // 受信した名前が既に登録されている場合 int count = 0; string newName; do { // 番号を付加する count++; newName = recvMsgMgr.Value + count.ToString(); } while (dicTcpClient.ContainsKey(newName)); tcpClientMgr.Name = newName; dicTcpClient.Add(newName, tcpClientMgr); } // List&Comboに追加 Invoke((Action)(() => { listBoxUser.Items.Add(tcpClientMgr.Name); cboxTarget.Items.Add(tcpClientMgr.Name); })); // 全体に接続情報を送信 // Connect,IP:Port,受信した名前,登録した名前 sendMsgMgr = new TcpMessageUtility(TcpMessageUtility.HeaderConnect, tcpClientMgr.GetClientIpAndPort(), recvMsgMgr.Value, tcpClientMgr.Name); TcpServerUtil.SendAll(sendMsgMgr.GetSendMessage()); break; case TcpMessageUtility.HeaderTargetMsg: // 送信元を設定 sendMsgMgr = new TcpMessageUtility(TcpMessageUtility.HeaderTargetMsg, tcpClientMgr.Name, recvMsgMgr.SendToTarget, recvMsgMgr.Value); Invoke((Action)(() => { listViewLog.Items.Add(sendMsgMgr.GetRecvTargetMessage()); })); // 受信したメッセージを対象に送信する // 名前→IP:Portへの変換 string toTarget = dicTcpClient[recvMsgMgr.SendToTarget].GetClientIpAndPort(); TcpServerUtil.SendTarget(toTarget, sendMsgMgr.GetSendMessage()); // 受信したメッセージを送信元に送信する // 名前→IP:Portへの変換 string fromTarget = tcpClientMgr.GetClientIpAndPort(); TcpServerUtil.SendTarget(fromTarget, sendMsgMgr.GetSendMessage()); break; case TcpMessageUtility.HeaderAllMsg: default: // 送信元を設定 sendMsgMgr = new TcpMessageUtility(TcpMessageUtility.HeaderAllMsg, tcpClientMgr.Name, recvMsgMgr.SendToTarget, recvMsgMgr.Value); Invoke((Action)(() => { listViewLog.Items.Add(sendMsgMgr.GetRecvTargetMessage()); })); // 受信したメッセージを全体に送信する TcpServerUtil.SendAll(sendMsgMgr.GetSendMessage()); break; } } } else { // 切断 Logger.WriteLine(nameof(ReadLoop), "切断されました。"); string deleteTargetIpAndPort = tcpClientMgr.GetClientIpAndPort(); _ = dicTcpClient.Remove(deleteTargetIpAndPort); TcpServerUtil.Delete(deleteTargetIpAndPort); return; } } } catch (Exception ex) { Debug.WriteLine(ex.ToString()); Logger.WriteException(nameof(ReadLoop), ex); } Logger.EndMethod(nameof(ReadLoop)); }