您的位置:首页 > 科技 > 能源 > 谷德设计网作品集_青岛做网站公司_百度网盘资源免费搜索引擎入口_重庆森林粤语

谷德设计网作品集_青岛做网站公司_百度网盘资源免费搜索引擎入口_重庆森林粤语

2025/3/20 18:55:08 来源:https://blog.csdn.net/weixin_47492910/article/details/146372900  浏览:    关键词:谷德设计网作品集_青岛做网站公司_百度网盘资源免费搜索引擎入口_重庆森林粤语
谷德设计网作品集_青岛做网站公司_百度网盘资源免费搜索引擎入口_重庆森林粤语

C#基于MVC模式实现TCP三次握手

  • 1 Model
    • 1.1 ServerModel
    • 1.2 ClientModel
    • 1.3 配置参数模块
    • 1.4 日志管理模块
      • 1.4.1 数据结构
      • 1.4.1 日志管理工具类
      • 1.4.1 日志视图展示
        • 1.4.1.1 UcLogManage.cs
        • 1.4.1.2 UcLogManage.Designer.cs
  • 2 视图(View)
    • 2.1 ViewServer
      • 2.1.1 ViewServer.cs
      • 2.1.1 ViewServer.Designer.cs
    • 2.2 ViewClient
      • 2.2.1 ViewClient.cs
      • 2.2.1 ViewClient.Designer.cs
  • 3 控制器(Controller)
    • 3.1 ServerController
    • 3.2 ClientController
  • 4 工具类

友情资料链接: TCP三次握手

1 Model

1.1 ServerModel

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;namespace DemoThreeTimesHandshake.Model
{public class ServerModel{private TcpListener _server;private bool _isRunning;public Action<TcpClient, Config.MyEnum, string> EventAddLog;~ServerModel(){CloseServer();}public void OpenServer(){//创建一个 TCP 监听器,监听本地 IP 地址和端口_server = new TcpListener(IPAddress.Any, Config.Server.Port);// 启动服务器_server.Start();_isRunning = true;new Task(() =>{while (_isRunning){Thread.Sleep(1000);ListeningClient();}}).Start();}public void CloseServer(){if (_isRunning){// 停止服务器_server.Stop();}}/// <summary>/// 监听接入客户端,三次握手/// </summary>private void ListeningClient(){TcpClient client = null;try{//等待客户端连接client = _server.AcceptTcpClient();AddLog(client, Config.MyEnum.State, "已连接");//获取网络流NetworkStream stream = client.GetStream();//第一次握手:接收客户端的 SYN 包byte[] buffer = new byte[1024];int bytesRead = stream.Read(buffer, 0, buffer.Length);string synMessage = Encoding.ASCII.GetString(buffer, 0, bytesRead);AddLog(client, Config.MyEnum.Receive, synMessage);//第二次握手:发送 SYN+ACK 包string synAckMessage = "SYN+ACK";byte[] synAckBuffer = Encoding.ASCII.GetBytes(synAckMessage);stream.Write(synAckBuffer, 0, synAckBuffer.Length);AddLog(client, Config.MyEnum.Send, synAckMessage);//第三次握手:接收客户端的 ACK 包bytesRead = stream.Read(buffer, 0, buffer.Length);string ackMessage = Encoding.ASCII.GetString(buffer, 0, bytesRead);AddLog(client, Config.MyEnum.Receive, ackMessage);AddLog(client, Config.MyEnum.State, "三次握手完成,连接建立成功。");//为(每个)客户端创建线程处理通信new Task(() => HandleClient(client)).Start();}catch (Exception ex){AddLog(client, Config.MyEnum.State, $"发生错误: {ex.Message}");}}private void HandleClient(TcpClient client){try{NetworkStream stream = client.GetStream();byte[] buffer = new byte[1024];while (_isRunning){// 异步读取客户端发送的消息int bytesRead = stream.Read(buffer, 0, buffer.Length);if (bytesRead == 0){// 客户端断开连接break;}string message = Encoding.ASCII.GetString(buffer, 0, bytesRead);AddLog(client, Config.MyEnum.Receive, message);// 将接收到消息回发给客户端string synMessage = message;byte[] synBuffer = System.Text.Encoding.ASCII.GetBytes(synMessage);stream.Write(synBuffer, 0, synBuffer.Length);AddLog(client, Config.MyEnum.Send, synMessage);}}catch (Exception ex){AddLog(client, Config.MyEnum.State, ex.Message);}}private void AddLog(TcpClient client, Config.MyEnum type, string description){EventAddLog?.Invoke(client, type, description);}}
}

1.2 ClientModel

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;namespace DemoThreeTimesHandshake.Model
{public class ClientModel{public Action<TcpClient, Config.MyEnum, string> EventAddLog;private TcpClient _client;private bool _isRunning;~ClientModel(){CloseServer();}public void OpenServer(){StartClient();}public void CloseServer(){if (_isRunning){_client.Close();}}private void StartClient(){try{// 创建一个 TCP 客户端,连接到服务器的 IP 地址和端口 8888_client = new TcpClient();_client.Connect(IPAddress.Parse(Config.Server.IP), Config.Server.Port);AddMsg(Config.MyEnum.State, "已连接到服务器。");_isRunning = true;// 获取网络流NetworkStream stream = _client.GetStream();// 第一次握手:发送 SYN 包string synMessage = "SYN";byte[] synBuffer = System.Text.Encoding.ASCII.GetBytes(synMessage);stream.Write(synBuffer, 0, synBuffer.Length);AddMsg(Config.MyEnum.Send, $"发送 SYN 包: {synMessage}");// 第二次握手:接收服务器的 SYN+ACK 包byte[] buffer = new byte[1024];int bytesRead = stream.Read(buffer, 0, buffer.Length);string synAckMessage = System.Text.Encoding.ASCII.GetString(buffer, 0, bytesRead);AddMsg(Config.MyEnum.Receive, $"收到服务器的 SYN+ACK 包: {synAckMessage}");// 第三次握手:发送 ACK 包string ackMessage = "ACK";byte[] ackBuffer = System.Text.Encoding.ASCII.GetBytes(ackMessage);stream.Write(ackBuffer, 0, ackBuffer.Length);AddMsg(Config.MyEnum.Send, $"发送 ACK 包: {ackMessage}");AddMsg(Config.MyEnum.State, "三次握手完成,连接建立成功。");// 客户端创建一个新的线程来处理通信new Task(HandleClient).Start();}catch (Exception ex){AddMsg(Config.MyEnum.State, $"异常: {ex.Message}");}}private void HandleClient(){try{NetworkStream stream = _client.GetStream();byte[] buffer = new byte[1024];while (_isRunning){// 异步读取客户端发送的消息int bytesRead = stream.Read(buffer, 0, buffer.Length);if (bytesRead == 0) break;string message = Encoding.ASCII.GetString(buffer, 0, bytesRead);AddMsg(Config.MyEnum.Receive, message);}}catch (Exception ex){AddMsg(Config.MyEnum.State, $"异常: {ex.Message}");}}private void AddMsg(Config.MyEnum type, string message){EventAddLog?.Invoke(_client, type, message);}public void Send(string textAsc){if (_client == null) return;// 获取网络流NetworkStream stream = _client.GetStream();byte[] synBuffer = Encoding.ASCII.GetBytes(textAsc);stream.Write(synBuffer, 0, synBuffer.Length);AddMsg(Config.MyEnum.Send, $"发送包长度: {synBuffer.Length}");}public void GetClientInfo(out string ip, out int port){try{IPEndPoint clientEndPoint = (IPEndPoint)_client.Client.RemoteEndPoint;ip = clientEndPoint.Address.ToString();port = clientEndPoint.Port;}catch (Exception ex){ip = "";port = 0;}}}
}

1.3 配置参数模块

using System;
using System.ComponentModel;namespace DemoThreeTimesHandshake.Model
{public class Config{public class Server{public const string IP = "127.0.0.1";public const int Port = 1234;}[Serializable]public enum MyEnum{[Description("状态信息")]State,[Description("发送")]Send,[Description("接受")]Receive}}
}

1.4 日志管理模块

1.4.1 数据结构

using System;
using System.ComponentModel;namespace DemoThreeTimesHandshake.Model.LogDS
{[Serializable]public class Log{[Description("时间")]public string Time { get; set; }[Description("IP")]public string IP { get; set; }[Description("类型")]public Config.MyEnum Type { get; set; }[Description("端口")]public int Port { get; set; }[Description("内容")]public string Description { get; set; }public Log(string time, string ip, int port, Config.MyEnum type, string description){Time = time;IP = ip;Port = port;Type = type;Description = description;}}
}

1.4.1 日志管理工具类

using System;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Windows.Forms;
using DemoThreeTimesHandshake.Tool;namespace DemoThreeTimesHandshake.Model.LogDS
{public class LogUtil{public enum ELog { First, Previous, Next, Last, Clear, Save }/// <summary>/// 记录日志信息/// </summary>private List<Log> _list = new List<Log>();/// <summary>/// 当前页索引/// </summary>private int _curPageIndex;private int _pageCount = 12;/// <summary>/// 日志元素数/// </summary>public int LogCount => _list.Count;/// <summary>/// 每页展示的数据量/// </summary>public int PageCount{get => _pageCount;set{_curPageIndex = 0;_pageCount = value;}}/// <summary>/// 总页数/// </summary>private int PageSum{get{int count = LogCount / PageCount;if (LogCount % PageCount > 0) count += 1;return count;}}/// <summary>/// 获取当前页(List)/// </summary>public List<Log> GetCurPage{get{var list = new List<Log>();for (int i = 0, index = _curPageIndex * PageCount; i < PageCount && index >= 0 && index < LogCount; i++, index++){list.Add(_list[index].DeepCopy());}return list;}}/// <summary>/// 获取当前页(DataTable)/// </summary>public DataTable GetCurPageTable{get{DataTable table = new DataTable();table.Columns.Add("序号");table.Columns.Add(nameof(Log.Time));table.Columns.Add(nameof(Log.IP));table.Columns.Add(nameof(Log.Type));table.Columns.Add(nameof(Log.Port));table.Columns.Add(nameof(Log.Description));for (int i = 0, index = _curPageIndex * PageCount; i < PageCount && index >= 0 && index < LogCount; i++, index++){var t = _list[index];table.Rows.Add(index + 1, t.Time, t.IP, t.Type, t.Port, t.Description);}return table;}}/// <summary>/// 当前页页码信息/// </summary>public string PageInfo => $"第{_curPageIndex + 1}页,共{PageSum}页";/// <summary>/// 添加日志/// </summary>/// <param name="ip"></param>/// <param name="port"></param>/// <param name="type"></param>/// <param name="description"></param>public void AddLog(string ip, int port, Config.MyEnum type, string description){var time = DateTime.Now.ToString("F");_list.Add(new Log(time, ip, port, type, description));_curPageIndex = PageSum - 1;}public void LogManage(ELog type){switch (type){case ELog.First:_curPageIndex = 0;break;case ELog.Previous:if (PageSum > 0){_curPageIndex -= 1;if (_curPageIndex < 0) _curPageIndex = PageSum - 1;}break;case ELog.Next:if (PageSum > 0) _curPageIndex = (_curPageIndex + 1) % PageSum;break;case ELog.Last:_curPageIndex = PageSum - 1;break;case ELog.Clear:_list.Clear();_curPageIndex = 0;break;case ELog.Save:SaveLog();break;}if (PageSum <= 0) _curPageIndex = 0;}public void SaveLog(){try{SaveFileDialog dialog = new SaveFileDialog();dialog.FileName = $"日志_{DateTime.Now:F}";dialog.Filter = "|*.csv";if (dialog.ShowDialog() != DialogResult.OK) return;string split = ",";StringBuilder builder = new StringBuilder();builder.Append("序号" + split);builder.Append(nameof(Log.Time) + split);builder.Append(nameof(Log.IP) + split);builder.Append(nameof(Log.Type) + split);builder.Append(nameof(Log.Port) + split);builder.Append(nameof(Log.Description));builder.AppendLine();int num = 1;foreach (var log in _list){builder.Append(num++ + split);builder.Append(log.Time + split);builder.Append(log.IP + split);builder.Append(log.Type + split);builder.Append(log.Port + split);builder.Append(log.Description);builder.AppendLine();}File.WriteAllText(dialog.FileName, builder.ToString());Process.Start(dialog.FileName);}catch (Exception ex){MessageBox.Show("保存日志文件失败:" + ex.Message);}}}
}

1.4.1 日志视图展示

在这里插入图片描述

1.4.1.1 UcLogManage.cs
using System;
using System.Linq;
using System.Windows.Forms;
using DemoThreeTimesHandshake.Tool;namespace DemoThreeTimesHandshake.Model.LogDS
{public partial class UcLogManage : UserControl{private LogUtil _logUtil;private string[] _hideColumnName;public UcLogManage(LogUtil logUtil, params string[] hideColumnName){InitializeComponent();_hideColumnName = hideColumnName;_logUtil = logUtil;menu_FirstPage.Click += (o, args) => ClickManage(LogUtil.ELog.First);menu_PreviousPage.Click += (o, args) => ClickManage(LogUtil.ELog.Previous);menu_NextPage.Click += (o, args) => ClickManage(LogUtil.ELog.Next);menu_LastPage.Click += (o, args) => ClickManage(LogUtil.ELog.Last);menu_ClearLog.Click += (o, args) => ClickManage(LogUtil.ELog.Clear);menu_SaveLog.Click += (o, args) => ClickManage(LogUtil.ELog.Save);com_PageCount.Text = logUtil.PageCount.ToString();com_PageCount.TextChanged += (o, args) =>{if (!int.TryParse(com_PageCount.Text, out var count)) return;_logUtil.PageCount = count;RefreshDataGridView();};menu_PageInfo.Text = string.Empty;}private void ClickManage(LogUtil.ELog type){_logUtil.LogManage(type);RefreshDataGridView();}private void RefreshDataGridView(){if (InvokeRequired){Invoke(new EventHandler(delegate { RefreshDataGridView(); }));return;}menu_PageInfo.Text = _logUtil.PageInfo;if (true){dataGridView1.DataSource = _logUtil.GetCurPageTable;}else{dataGridView1.DataSource = _logUtil.GetCurPage.ToList();}dataGridView1.Columns["序号"].FillWeight = 1;SetDataGridViewStyle(nameof(Log.Time), 2);SetDataGridViewStyle(nameof(Log.IP), 1);SetDataGridViewStyle(nameof(Log.Port), 1);SetDataGridViewStyle(nameof(Log.Type), 1);SetDataGridViewStyle(nameof(Log.Description), 5);for (int i = 0; i < _hideColumnName.Length; i++){dataGridView1.Columns[_hideColumnName[i]].Visible = false;}Utility.SetDgvStyle(dataGridView1);}private void SetDataGridViewStyle(string propertyName, int fillWeight){string headerText = Utility.GetPropertyDescription<Log>(propertyName);dataGridView1.Columns[propertyName].HeaderText = headerText;dataGridView1.Columns[propertyName].FillWeight = fillWeight;}public void DisplayResult(){RefreshDataGridView();}}
}
1.4.1.2 UcLogManage.Designer.cs
namespace DemoThreeTimesHandshake.Model.LogDS
{partial class UcLogManage{/// <summary> /// 必需的设计器变量。/// </summary>private System.ComponentModel.IContainer components = null;/// <summary> /// 清理所有正在使用的资源。/// </summary>/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>protected override void Dispose(bool disposing){if (disposing && (components != null)){components.Dispose();}base.Dispose(disposing);}#region 组件设计器生成的代码/// <summary> /// 设计器支持所需的方法 - 不要修改/// 使用代码编辑器修改此方法的内容。/// </summary>private void InitializeComponent(){this.menuStrip1 = new System.Windows.Forms.MenuStrip();this.menu_FirstPage = new System.Windows.Forms.ToolStripMenuItem();this.menu_PreviousPage = new System.Windows.Forms.ToolStripMenuItem();this.menu_NextPage = new System.Windows.Forms.ToolStripMenuItem();this.menu_LastPage = new System.Windows.Forms.ToolStripMenuItem();this.menu_ClearLog = new System.Windows.Forms.ToolStripMenuItem();this.menu_PageInfo = new System.Windows.Forms.ToolStripMenuItem();this.menu_LogManage = new System.Windows.Forms.ToolStripMenuItem();this.dataGridView1 = new System.Windows.Forms.DataGridView();this.menu_SaveLog = new System.Windows.Forms.ToolStripMenuItem();this.每页显示日志条数ToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();this.com_PageCount = new System.Windows.Forms.ToolStripComboBox();this.menuStrip1.SuspendLayout();((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();this.SuspendLayout();// // menuStrip1// this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {this.menu_LogManage,this.menu_FirstPage,this.menu_PreviousPage,this.menu_NextPage,this.menu_LastPage,this.menu_ClearLog,this.menu_PageInfo});this.menuStrip1.Location = new System.Drawing.Point(0, 0);this.menuStrip1.Name = "menuStrip1";this.menuStrip1.Size = new System.Drawing.Size(703, 25);this.menuStrip1.TabIndex = 9;this.menuStrip1.Text = "menuStrip1";// // menu_FirstPage// this.menu_FirstPage.Name = "menu_FirstPage";this.menu_FirstPage.Size = new System.Drawing.Size(44, 21);this.menu_FirstPage.Text = "首页";// // menu_PreviousPage// this.menu_PreviousPage.Name = "menu_PreviousPage";this.menu_PreviousPage.Size = new System.Drawing.Size(56, 21);this.menu_PreviousPage.Text = "上一页";// // menu_NextPage// this.menu_NextPage.Name = "menu_NextPage";this.menu_NextPage.Size = new System.Drawing.Size(56, 21);this.menu_NextPage.Text = "下一页";// // menu_LastPage// this.menu_LastPage.Name = "menu_LastPage";this.menu_LastPage.Size = new System.Drawing.Size(44, 21);this.menu_LastPage.Text = "尾页";// // menu_ClearLog// this.menu_ClearLog.Name = "menu_ClearLog";this.menu_ClearLog.Size = new System.Drawing.Size(68, 21);this.menu_ClearLog.Text = "清空日志";// // menu_PageInfo// this.menu_PageInfo.Name = "menu_PageInfo";this.menu_PageInfo.Padding = new System.Windows.Forms.Padding(100, 0, 4, 0);this.menu_PageInfo.Size = new System.Drawing.Size(164, 21);this.menu_PageInfo.Text = "页码信息";// // menu_LogManage// this.menu_LogManage.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {this.menu_SaveLog,this.每页显示日志条数ToolStripMenuItem});this.menu_LogManage.Name = "menu_LogManage";this.menu_LogManage.Padding = new System.Windows.Forms.Padding(50, 0, 4, 0);this.menu_LogManage.Size = new System.Drawing.Size(114, 21);this.menu_LogManage.Text = "管理日志";// // dataGridView1// this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;this.dataGridView1.Dock = System.Windows.Forms.DockStyle.Fill;this.dataGridView1.Location = new System.Drawing.Point(0, 25);this.dataGridView1.Name = "dataGridView1";this.dataGridView1.RowTemplate.Height = 23;this.dataGridView1.Size = new System.Drawing.Size(703, 304);this.dataGridView1.TabIndex = 10;// // menu_SaveLog// this.menu_SaveLog.Name = "menu_SaveLog";this.menu_SaveLog.Size = new System.Drawing.Size(180, 22);this.menu_SaveLog.Text = "保存日志";// // 每页显示日志条数ToolStripMenuItem// this.每页显示日志条数ToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {this.com_PageCount});this.每页显示日志条数ToolStripMenuItem.Name = "每页显示日志条数ToolStripMenuItem";this.每页显示日志条数ToolStripMenuItem.Size = new System.Drawing.Size(180, 22);this.每页显示日志条数ToolStripMenuItem.Text = "每页显示日志条数";// // com_PageCount// this.com_PageCount.Items.AddRange(new object[] {"5","10","15","20","25","30"});this.com_PageCount.Name = "com_PageCount";this.com_PageCount.Size = new System.Drawing.Size(121, 25);// // UcLogManage// this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;this.Controls.Add(this.dataGridView1);this.Controls.Add(this.menuStrip1);this.Name = "UcLogManage";this.Size = new System.Drawing.Size(703, 329);this.menuStrip1.ResumeLayout(false);this.menuStrip1.PerformLayout();((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();this.ResumeLayout(false);this.PerformLayout();}#endregionprivate System.Windows.Forms.MenuStrip menuStrip1;private System.Windows.Forms.ToolStripMenuItem menu_PreviousPage;private System.Windows.Forms.ToolStripMenuItem menu_NextPage;private System.Windows.Forms.DataGridView dataGridView1;private System.Windows.Forms.ToolStripMenuItem menu_ClearLog;private System.Windows.Forms.ToolStripMenuItem menu_PageInfo;private System.Windows.Forms.ToolStripMenuItem menu_FirstPage;private System.Windows.Forms.ToolStripMenuItem menu_LastPage;private System.Windows.Forms.ToolStripMenuItem menu_LogManage;private System.Windows.Forms.ToolStripMenuItem menu_SaveLog;private System.Windows.Forms.ToolStripMenuItem 每页显示日志条数ToolStripMenuItem;private System.Windows.Forms.ToolStripComboBox com_PageCount;}
}

2 视图(View)

2.1 ViewServer

2.1.1 ViewServer.cs

using System;
using System.Windows.Forms;
using DemoThreeTimesHandshake.Controller;
using DemoThreeTimesHandshake.Model;
using DemoThreeTimesHandshake.Model.LogDS;namespace DemoThreeTimesHandshake.View
{public partial class ViewServer : Form{public readonly LogUtil Log = new LogUtil();public Action EventStartServer;public Action EventDisplayLog;public ViewServer(){InitializeComponent();this.WindowState = FormWindowState.Maximized;var ucLogManage = new UcLogManage(Log) { Dock = DockStyle.Fill };EventDisplayLog += ucLogManage.DisplayResult;panel1.Controls.Add(ucLogManage);_ = new ServerController(this, new ServerModel());}private void menu_OpenClientForm_Click(object sender, EventArgs e) => new ViewClient().Show();private void menu_StartServer_Click(object sender, EventArgs e){EventStartServer?.Invoke();}public void DisplayResult(){menu_StartServer.Enabled = false;this.Text = "服务器,状态:已启动,等待客户端连接...";}}
}

2.1.1 ViewServer.Designer.cs

namespace DemoThreeTimesHandshake.View
{partial class ViewServer{/// <summary>/// Required designer variable./// </summary>private System.ComponentModel.IContainer components = null;/// <summary>/// Clean up any resources being used./// </summary>/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>protected override void Dispose(bool disposing){if (disposing && (components != null)){components.Dispose();}base.Dispose(disposing);}#region Windows Form Designer generated code/// <summary>/// Required method for Designer support - do not modify/// the contents of this method with the code editor./// </summary>private void InitializeComponent(){this.menuStrip1 = new System.Windows.Forms.MenuStrip();this.menu_StartServer = new System.Windows.Forms.ToolStripMenuItem();this.menu_OpenClientForm = new System.Windows.Forms.ToolStripMenuItem();this.panel1 = new System.Windows.Forms.Panel();this.menuStrip1.SuspendLayout();this.SuspendLayout();// // menuStrip1// this.menuStrip1.Font = new System.Drawing.Font("Microsoft YaHei UI", 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(134)));this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {this.menu_StartServer,this.menu_OpenClientForm});this.menuStrip1.Location = new System.Drawing.Point(0, 0);this.menuStrip1.Name = "menuStrip1";this.menuStrip1.Size = new System.Drawing.Size(824, 30);this.menuStrip1.TabIndex = 10;this.menuStrip1.Text = "menuStrip1";// // menu_StartServer// this.menu_StartServer.Name = "menu_StartServer";this.menu_StartServer.Size = new System.Drawing.Size(102, 26);this.menu_StartServer.Text = "开启服务器";this.menu_StartServer.Click += new System.EventHandler(this.menu_StartServer_Click);// // menu_OpenClientForm// this.menu_OpenClientForm.Name = "menu_OpenClientForm";this.menu_OpenClientForm.Size = new System.Drawing.Size(134, 26);this.menu_OpenClientForm.Text = "打开客户端窗口";this.menu_OpenClientForm.Click += new System.EventHandler(this.menu_OpenClientForm_Click);// // panel1// this.panel1.Dock = System.Windows.Forms.DockStyle.Fill;this.panel1.Location = new System.Drawing.Point(0, 30);this.panel1.Name = "panel1";this.panel1.Size = new System.Drawing.Size(824, 402);this.panel1.TabIndex = 11;// // ViewServer// this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;this.ClientSize = new System.Drawing.Size(824, 432);this.Controls.Add(this.panel1);this.Controls.Add(this.menuStrip1);this.Name = "ViewServer";this.Text = "服务器,状态:未开启";this.menuStrip1.ResumeLayout(false);this.menuStrip1.PerformLayout();this.ResumeLayout(false);this.PerformLayout();}#endregionprivate System.Windows.Forms.MenuStrip menuStrip1;private System.Windows.Forms.ToolStripMenuItem menu_StartServer;private System.Windows.Forms.ToolStripMenuItem menu_OpenClientForm;private System.Windows.Forms.Panel panel1;}
}

2.2 ViewClient

2.2.1 ViewClient.cs

using System;
using System.Windows.Forms;
using DemoThreeTimesHandshake.Controller;
using DemoThreeTimesHandshake.Model;
using DemoThreeTimesHandshake.Model.LogDS;namespace DemoThreeTimesHandshake.View
{public partial class ViewClient : Form{public EventHandler<ClientEventManage> EventManage;public Action EventDisplayLog;public readonly LogUtil LogUtil = new LogUtil();public ViewClient(){InitializeComponent();this.TopMost = true;_ = new ClientController(this, new ClientModel());var ucLogManage = new UcLogManage(LogUtil, nameof(Log.IP), nameof(Log.Port)) { Dock = DockStyle.Fill };EventDisplayLog += ucLogManage.DisplayResult;panel1.Controls.Add(ucLogManage);}private void menu_StartClient_Click(object sender, EventArgs e){EventManage?.Invoke(this, new ClientEventManage(EEventType.Open));}private void button1_Click(object sender, EventArgs e){EventManage?.Invoke(this, new ClientEventManage(EEventType.Send, textBox1.Text));}public void DisplayResult(string ip, int port){if (InvokeRequired){Invoke(new EventHandler(delegate { DisplayResult(ip, port); }));}else{menu_StartClient.Enabled = false;this.Text = $"客户端,状态:已连接,IP = {ip},端口 = {port}";}}}public enum EEventType { Open, Send }public class ClientEventManage : EventArgs{public EEventType Type { get; set; }public string Message { get; set; }public ClientEventManage(EEventType type, string message){Type = type;Message = message;}public ClientEventManage(EEventType type){Type = type;}}
}

2.2.1 ViewClient.Designer.cs

namespace DemoThreeTimesHandshake.View
{partial class ViewClient{/// <summary>/// Required designer variable./// </summary>private System.ComponentModel.IContainer components = null;/// <summary>/// Clean up any resources being used./// </summary>/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>protected override void Dispose(bool disposing){if (disposing && (components != null)){components.Dispose();}base.Dispose(disposing);}#region Windows Form Designer generated code/// <summary>/// Required method for Designer support - do not modify/// the contents of this method with the code editor./// </summary>private void InitializeComponent(){this.button1 = new System.Windows.Forms.Button();this.menuStrip1 = new System.Windows.Forms.MenuStrip();this.menu_StartClient = new System.Windows.Forms.ToolStripMenuItem();this.textBox1 = new System.Windows.Forms.TextBox();this.panel1 = new System.Windows.Forms.Panel();this.menuStrip1.SuspendLayout();this.SuspendLayout();// // button1// this.button1.Location = new System.Drawing.Point(210, 40);this.button1.Name = "button1";this.button1.Size = new System.Drawing.Size(78, 21);this.button1.TabIndex = 5;this.button1.Text = "发送";this.button1.UseVisualStyleBackColor = true;this.button1.Click += new System.EventHandler(this.button1_Click);// // menuStrip1// this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {this.menu_StartClient});this.menuStrip1.Location = new System.Drawing.Point(0, 0);this.menuStrip1.Name = "menuStrip1";this.menuStrip1.Size = new System.Drawing.Size(793, 25);this.menuStrip1.TabIndex = 6;this.menuStrip1.Text = "menuStrip1";// // menu_StartClient// this.menu_StartClient.Name = "menu_StartClient";this.menu_StartClient.Size = new System.Drawing.Size(80, 21);this.menu_StartClient.Text = "启动客户端";this.menu_StartClient.Click += new System.EventHandler(this.menu_StartClient_Click);// // textBox1// this.textBox1.Location = new System.Drawing.Point(35, 40);this.textBox1.Name = "textBox1";this.textBox1.Size = new System.Drawing.Size(148, 21);this.textBox1.TabIndex = 7;// // panel1// this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right)));this.panel1.Location = new System.Drawing.Point(35, 99);this.panel1.Name = "panel1";this.panel1.Size = new System.Drawing.Size(731, 365);this.panel1.TabIndex = 8;// // ViewClient// this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;this.ClientSize = new System.Drawing.Size(793, 494);this.Controls.Add(this.panel1);this.Controls.Add(this.textBox1);this.Controls.Add(this.button1);this.Controls.Add(this.menuStrip1);this.MainMenuStrip = this.menuStrip1;this.Name = "ViewClient";this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;this.Text = "客户端,状态:未连接";this.menuStrip1.ResumeLayout(false);this.menuStrip1.PerformLayout();this.ResumeLayout(false);this.PerformLayout();}#endregionprivate System.Windows.Forms.Button button1;private System.Windows.Forms.MenuStrip menuStrip1;private System.Windows.Forms.ToolStripMenuItem menu_StartClient;private System.Windows.Forms.TextBox textBox1;private System.Windows.Forms.Panel panel1;}
}

3 控制器(Controller)

3.1 ServerController

using System.Net.Sockets;
using DemoThreeTimesHandshake.Model;
using DemoThreeTimesHandshake.Tool;
using DemoThreeTimesHandshake.View;namespace DemoThreeTimesHandshake.Controller
{public class ServerController{private readonly ViewServer _view;private readonly ServerModel _model;public ServerController(ViewServer view, ServerModel model){_view = view;_model = model;_view.EventStartServer += OnEventStartServer;_model.EventAddLog += OnAddLog;}private void OnEventStartServer(){_model.OpenServer();_view.DisplayResult();}private void OnAddLog(TcpClient client, Config.MyEnum type, string description){Utility.GetClientInfo(client, out string ip, out int port);_view.Log.AddLog(ip, port, type, description);_view.EventDisplayLog?.Invoke();}}
}

3.2 ClientController

using System.Net.Sockets;
using System.Threading.Tasks;
using DemoThreeTimesHandshake.Model;
using DemoThreeTimesHandshake.View;namespace DemoThreeTimesHandshake.Controller
{public class ClientController{private readonly ViewClient _view;private readonly ClientModel _model;public ClientController(ViewClient view, ClientModel model){_view = view;_model = model;_view.EventManage += OnEventStartClient;_model.EventAddLog += OnAddLog;}private void OnEventStartClient(object obj, ClientEventManage e){switch (e.Type){case EEventType.Open:new Task(() =>{_model.OpenServer();_model.GetClientInfo(out string ip, out int port);_view.DisplayResult(ip, port);}).Start();break;case EEventType.Send:_model.Send(e.Message);break;}}private void OnAddLog(TcpClient client, Config.MyEnum type, string description){_model.GetClientInfo(out string ip, out int port);_view.LogUtil.AddLog(ip, port, type, description);_view.EventDisplayLog?.Invoke();}}
}

4 工具类

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Runtime.Serialization.Formatters.Binary;
using System.Windows.Forms;namespace DemoThreeTimesHandshake.Tool
{public static class Utility{private static readonly Dictionary<string, string> descriptionCache = new Dictionary<string, string>();/// <summary>/// 获取属性/枚举成员的Description/// </summary>public static string GetPropertyDescription<T>(string propertyName){string cacheKey = $"{typeof(T).FullName}.{propertyName}";if (descriptionCache.TryGetValue(cacheKey, out string description)){return description;}Type type = typeof(T);PropertyInfo property = type.GetProperty(propertyName);if (property != null){DescriptionAttribute descriptionAttribute = property.GetCustomAttribute<DescriptionAttribute>();if (descriptionAttribute != null){description = descriptionAttribute.Description;descriptionCache[cacheKey] = description;return description;}}FieldInfo field = type.GetField(propertyName);if (field != null){DescriptionAttribute descriptionAttribute = field.GetCustomAttribute<DescriptionAttribute>();if (descriptionAttribute != null){description = descriptionAttribute.Description;descriptionCache[cacheKey] = description;return description;}}return null;}/// <summary>/// 设置DataGridView样式/// </summary>public static void SetDgvStyle(DataGridView table){try{table.ClearSelection();//int index = dgvStandard.CurrentCell.RowIndex;//获取选中行table.MultiSelect = false; //不可多选table.AllowUserToAddRows = false; //设置不显示添加行table.AllowUserToDeleteRows = false; //设置不允许删除行table.AllowUserToResizeColumns = false; //设置列不可调整table.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter; //列名居中table.AllowUserToResizeRows = false; //设置行不可调整table.RowHeadersVisible = false; //设置表头不显示行标题table.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill; //列填充控件显示区域table.CausesValidation = false; //焦点table.ColumnHeadersBorderStyle = DataGridViewHeaderBorderStyle.Single; //边框样式table.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize; //列高调整table.RowsDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter; //单元格内容居中table.ReadOnly = false; //只读设置table.RowHeadersWidth = 4; //列宽设置(按照权重设置时需要先添加列)table.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders; //设置列表头不可调整table.RowTemplate.Height = 28; //设置行高table.ScrollBars = ScrollBars.Vertical; //显示垂直滚动条table.TabStop = false; //设置无Tab焦点table.VirtualMode = true; //设置可进行数据管理//table.Rows[lastTableHeadRow].Frozen = true;//冻结指定行for (var i = 0; i < table.Columns.Count; i++){//table.Columns[i].SortMode = DataGridViewColumnSortMode.NotSortable; //禁止点击列名排序//table.Columns[i].FillWeight = 1; //按权重分配列宽//设置图像列的布局//var column = table.Columns[i] as DataGridViewImageColumn;//if (column != null)//{//    column.ImageLayout = DataGridViewImageCellLayout.Zoom;//}}}catch (Exception){// ignored}}/// <summary>/// 获取客户端信息/// </summary>public static void GetClientInfo(TcpClient client, out string ip, out int port){try{IPEndPoint clientEndPoint = (IPEndPoint)client.Client.RemoteEndPoint;ip = clientEndPoint.Address.ToString();port = clientEndPoint.Port;}catch{ip = "";port = 0;}}/// <summary>/// 深度拷贝/// </summary>public static T DeepCopy<T>(this T obj){if (!obj.GetType().IsSerializable){return default(T);}using (MemoryStream ms = new MemoryStream()){BinaryFormatter formatter = new BinaryFormatter();formatter.Serialize(ms, obj);ms.Position = 0;return (T)formatter.Deserialize(ms);}}/// <summary>/// 获取时间戳/// </summary>/// <returns></returns>public static long GetTimeLong(){long unixTimestampMs = (long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds;return unixTimestampMs;}}
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com