再次修正,客户端用C#.

作者:欧阳佳

再次修正我们的语言选择,

我查阅了很多相关资料.

发现,要做出那种浮动形式的小巧软件.

很不容易.

这方面的技术用VC++比较合适.

可我们组会VC++的没有一人.

所以临时改用C#.NET.

迫不得已,想要开发最好的东西,就必须用自己会的东西.

 我会马上通知其他组员

帮我检查下代码和修正优化下:TcpCommunication.cs、Form1.cs文件的代码。以下是TcpCommunication.cs的代码using System; using System.IO; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; using System.Threading.Tasks; namespace _20250721test类 { public class TcpCommunication { // 属性声明(与窗体控件对应) public string IPAddress_str { get; set; } = "127.0.0.1"; public int Port { get; set; } = 8080; public bool IsClientMode { get; set; } = true; public bool IsOpen => _tcpClient?.Connected ?? false; public string ReceivedData { get; private set; } = ""; public string LastError { get; private set; } = ""; // 新增服务器监听状态属性 public bool IsListening { get; private set; } = false; // 核心对象 private TcpListener _tcpServer; private TcpClient _tcpClient; private NetworkStream _stream; private Thread _receiveThread; private bool _isRunning; // 事件定义 public delegate void DataReceivedHandler(string data); public event DataReceivedHandler DataReceived; public delegate void ConnectionStateHandler(bool isConnected); public event ConnectionStateHandler ConnectionStateChanged; public delegate void ErrorHandler(string errorMessage); public event ErrorHandler ErrorOccurred; // 新增服务器监听状态事件 public delegate void ServerListeningHandler(bool isListening); public event ServerListeningHandler ServerListeningChanged; /// <summary> /// 打开TCP连接(客户端或服务器) /// </summary> public void Open() { try { if (IsClientMode) { // 客户端模式不变 _tcpClient = new TcpClient(); _tcpClient.Connect(IPAddress.Parse(IPAddress_str), Port); _stream = _tcpClient.GetStream(); _isRunning = true; StartReceiving(); ConnectionStateChanged?.Invoke(true); // 连接成功 } else { // 服务器模式:启动监听 _tcpServer = new TcpListener(IPAddress.Parse(IPAddress_str), Port); _tcpServer.Start(); IsListening = true; // 设置监听状态 // 立即触发监听状态事件 ServerListeningChanged?.Invoke(true); // 异步等待客户端连接 _tcpServer.BeginAcceptTcpClient(AcceptClientCallback, null); } } catch (Exception ex) { RecordError($"启动失败: {ex.Message}"); } } // 客户端连接回调 private void AcceptClientCallback(IAsyncResult ar) { try { _tcpClient = _tcpServer.EndAcceptTcpClient(ar); _stream = _tcpClient.GetStream(); _isRunning = true; StartReceiving(); // 客户端连接后触发连接状态 ConnectionStateChanged?.Invoke(true); } catch (Exception ex) { RecordError($"客户端连接失败: {ex.Message}"); } } /// <summary> /// 关闭TCP连接 /// </summary> public void Close() { try { _isRunning = false; _stream?.Close(); _tcpClient?.Close(); if (!IsClientMode) { _tcpServer?.Stop(); } ConnectionStateChanged?.Invoke(false); RecordStatus("连接已关闭"); } catch (Exception ex) { RecordError($"关闭异常: {ex.Message}"); } // 重置监听状态 if (!IsClientMode && IsListening) { IsListening = false; ServerListeningChanged?.Invoke(false); } } /// <summary> /// 发送数据 /// </summary> public void Send(string data) { if (!IsOpen || string.IsNullOrEmpty(data)) return; try { byte[] buffer = Encoding.UTF8.GetBytes(data); _stream.Write(buffer, 0, buffer.Length); _stream.Flush(); } catch (Exception ex) { RecordError($"发送失败: {ex.Message}"); Close(); // 发生错误时自动关闭连接 } } // 启动接收线程 private void StartReceiving() { _receiveThread = new Thread(() => { byte[] buffer = new byte[4096]; while (_isRunning && IsOpen) { try { if (_stream.DataAvailable) { int bytesRead = _stream.Read(buffer, 0, buffer.Length); if (bytesRead > 0) { string received = Encoding.UTF8.GetString(buffer, 0, bytesRead); ReceivedData = received; DataReceived?.Invoke(received); } } Thread.Sleep(50); // 降低CPU占用 } catch (IOException ex) when (ex.InnerException is SocketException) { RecordError($"连接异常中断: {ex.Message}"); Close(); break; } catch (Exception ex) { RecordError($"接收错误: {ex.Message}"); Thread.Sleep(1000); } } }) { IsBackground = true }; _receiveThread.Start(); } // 错误记录方法 private void RecordError(string message) { LastError = $"[{DateTime.Now:HH:mm:ss}] {message}"; ErrorOccurred?.Invoke(LastError); } private void RecordStatus(string message) { } } } 以下是Form1.cs的代码:using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO.Ports; using System.Linq; using System.Reflection.Emit; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; using System.Net.Sockets; namespace _20250721test类 { public partial class Form1 : Form { private SerialPortManager sPortManager = new SerialPortManager(); // 在窗体类中声明通信对象 private TcpCommunication _tcpComm = new TcpCommunication(); public Form1() { InitializeComponent(); sPortManager.DataReceived += UpdateReceivedData; } private void Form1_Load(object sender, EventArgs e) { btn_openClose.Text = "打开"; lbl_connState.Text = "断开"; lbl_connState.BackColor = Color.Red; string[] portNames = SerialPort.GetPortNames(); // 获取所有可用串口的名字[^3] foreach (string portName in portNames) { cbo_com.Items.Add(portName); // 将每个串口名字添加到组合框中[^4] } // 绑定事件 _tcpComm.DataReceived += OnDataReceived; _tcpComm.ConnectionStateChanged += OnConnectionStateChanged; _tcpComm.ErrorOccurred += OnErrorOccurred; // 注册新事件 _tcpComm.ServerListeningChanged += OnServerListeningChanged; _tcpComm.ConnectionStateChanged += OnConnectionStateChanged; // 初始状态 UpdateUIState(); // 初始化控件 txt_IPaddress.Text = "127.0.0.1"; txt_IPport.Text = "5000"; cbo_IPClientServer.SelectedIndex = 0; } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { _tcpComm.Close(); sPortManager.Close(); } private void btn_openClose_Click(object sender, EventArgs e) { if (btn_openClose.Text == "打开") { try { // 停止位转换(兼容C# 7.3) StopBits stopBits; switch (cbo_stopBit.Text) { case "1": stopBits = StopBits.One; break; case "1.5": stopBits = StopBits.OnePointFive; break; case "2": stopBits = StopBits.Two; break; default: stopBits = StopBits.One; break; } // 校验位转换(兼容C# 7.3) Parity parity; switch (cbo_parity.Text) { case "无": parity = Parity.None; break; case "奇校验": parity = Parity.Odd; break; case "偶校验": parity = Parity.Even; break; default: parity = Parity.None; break; } sPortManager.Open( cbo_com.Text, int.Parse(cbo_baudRate.Text), int.Parse(cbo_databit.Text), stopBits, parity, cbo_receiveEnd.Text ); if (sPortManager.IsOpen) { btn_openClose.Text = "关闭"; lbl_connState.Text = "连接"; lbl_connState.BackColor = Color.Lime; } } catch { MessageBox.Show("串口连接失败"); } } else { sPortManager.Close(); btn_openClose.Text = "打开"; lbl_connState.Text = "断开"; lbl_connState.BackColor = Color.Red; } } private void btn_send_Click(object sender, EventArgs e) { sPortManager.Send(txt_sendData.Text); } private void UpdateReceivedData(string data) { if (lbl_sPreceive.InvokeRequired) { lbl_sPreceive.Invoke(new Action(() => lbl_sPreceive.Text = data)); } else { lbl_sPreceive.Text = data; } } private void btn_IPopenClose_Click(object sender, EventArgs e) { if (_tcpComm.IsClientMode) { // 客户端模式逻辑不变 if (!_tcpComm.IsOpen) { _tcpComm.IPAddress_str = txt_IPaddress.Text; _tcpComm.Port = int.Parse(txt_IPport.Text); _tcpComm.IsClientMode = (cbo_IPClientServer.SelectedItem.ToString() == "Client"); _tcpComm.Open(); } else _tcpComm.Close(); } else { // 服务器模式:根据监听状态切换 if (!_tcpComm.IsListening) { _tcpComm.IPAddress_str = txt_IPaddress.Text; _tcpComm.Port = int.Parse(txt_IPport.Text); _tcpComm.IsClientMode = (cbo_IPClientServer.SelectedItem.ToString() == "Server"); _tcpComm.Open(); // 启动监听 } else _tcpComm.Close(); // 停止监听 } } private void beiyong() { if (!_tcpComm.IsOpen) { // 配置参数 _tcpComm.IPAddress_str = txt_IPaddress.Text; _tcpComm.Port = int.Parse(txt_IPport.Text); _tcpComm.IsClientMode = (cbo_IPClientServer.SelectedItem.ToString() == "Client"); // 打开连接 _tcpComm.Open(); } else { _tcpComm.Close(); } } private void btn_IPsend_Click(object sender, EventArgs e) { string data = txt_IPsendData.Text; if (!string.IsNullOrEmpty(data)) { _tcpComm.Send(data); } } // 窗体状态处理 private void OnServerListeningChanged(bool isListening) { this.Invoke((MethodInvoker)delegate { if (!_tcpComm.IsClientMode) { // 服务器监听状态更新 lbl_IPconnState.Text = isListening ? "监听中..." : "已断开"; lbl_IPconnState.BackColor = isListening ? Color.Yellow : Color.Red; if (isListening == true) { LogToTextBox("服务器模式-监听中..."); } else if (isListening == false) { LogToTextBox("服务器模式-已断开"); } btn_IPopenClose.Text = isListening ? "停止监听" : "开始监听"; } }); } // 事件处理方法 private void OnDataReceived(string data) { // 跨线程更新UI this.Invoke((MethodInvoker)delegate { lbl_IPreceive.Text = data; txt_IPreceiveLog.AppendText($"[接收] {DateTime.Now:HH:mm:ss}: {data}{Environment.NewLine}"); }); } private void OnConnectionStateChanged(bool isConnected) { this.Invoke((MethodInvoker)delegate { if (_tcpComm.IsClientMode) { // 客户端模式 lbl_IPconnState.Text = isConnected ? "已连接" : "已断开"; lbl_IPconnState.BackColor = isConnected ? Color.Lime : Color.Red; if (isConnected == true) { LogToTextBox("客户端模式-已连接"); } else if (isConnected == false) { LogToTextBox("客户端模式-已断开"); } btn_IPopenClose.Text = isConnected ? "关闭连接" : "打开连接"; } else { // 服务器模式:已连接客户端 if (isConnected) { lbl_IPconnState.Text = "已连接 (1客户端)"; lbl_IPconnState.BackColor = Color.Lime; LogToTextBox("服务器模式-已连接"); } // 监听状态由OnServerListeningChanged单独处理 } }); } // 统一UI状态更新 private void UpdateUIState() { if (_tcpComm.IsClientMode) { // 客户端模式初始状态 lbl_IPconnState.Text = "已断开"; lbl_IPconnState.BackColor = Color.Red; btn_IPopenClose.Text = "打开连接"; } else { // 服务器模式初始状态 lbl_IPconnState.Text = "未监听"; lbl_IPconnState.BackColor = Color.Red; btn_IPopenClose.Text = "开始监听"; } } private void OnErrorOccurred(string error) { this.Invoke((MethodInvoker)delegate { txt_ErrorLog.AppendText($"{error}{Environment.NewLine}"); MessageBox.Show($"通信错误: {error}", "系统警告", MessageBoxButtons.OK, MessageBoxIcon.Warning); }); } private void LogToTextBox(string message) { if (txt_ErrorLog.InvokeRequired) { txt_ErrorLog.Invoke(new Action(() => { txt_ErrorLog.AppendText($"[{DateTime.Now:HH:mm:ss}] {message}\n"); txt_ErrorLog.ScrollToCaret(); })); } else { txt_ErrorLog.AppendText($"[{DateTime.Now:HH:mm:ss}] {message}\n"); txt_ErrorLog.ScrollToCaret(); } } } } 注意界面的txt、cbo、lbl控件已经存在的
07-23
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值