wordpress cms系统,什么杭州seo公司,dw软件怎么制作网页,wordpress 换 ip文章的目的为了记录使用C# 开发学习的经历。开发流程和要点有些记忆模糊#xff0c;赶紧记录#xff0c;防止忘记。 相关链接#xff1a;
开源 C# 快速开发#xff08;一#xff09;基础知识
开源 C# 快速开发#xff08;二#xff09;基础控件
开源 C# 快速开发赶紧记录防止忘记。 相关链接
开源 C# 快速开发一基础知识
开源 C# 快速开发二基础控件
开源 C# 快速开发三复杂控件
开源 C# 快速开发四自定义控件--波形图
开源 C# 快速开发五自定义控件--仪表盘
开源 C# 快速开发六自定义控件--圆环
开源 C# 快速开发七通讯--串口
开源 C# 快速开发八通讯--Tcp服务器端
开源 C# 快速开发九通讯--Tcp客户端
开源 C# 快速开发十通讯--http客户端 推荐链接:
开源 C# .net mvc 开发一WEB搭建_c#部署web程序-CSDN博客
开源 C# .net mvc 开发二网站快速搭建_c#网站开发-CSDN博客
开源 C# .net mvc 开发三WEB内外网访问-CSDN博客
开源 C# .net mvc 开发四工程结构、页面提交以及显示-CSDN博客
开源 C# .net mvc 开发五常用代码快速开发_c# mvc开发-CSDN博客
开源 C# .net mvc 开发六发送邮件、定时以及CMD编程-CSDN博客
开源 C# .net mvc 开发七动态图片、动态表格和json数据生成-CSDN博客
开源 C# .net mvc 开发八IIS Express轻量化Web服务器的配置和使用-CSDN博客
开源 C# .net mvc 开发九websocket--服务器与客户端的实时通信-CSDN博客 本章节主要内容是:Tcp服务器端程序基于Windows Forms和串口控件实现。 目录
1.源码分析
2.所有源码
3.效果演示 一、源码分析
1. 构造函数 TcpServerForm()
功能分析
初始化窗体组件通过InitializeComponent()
创建空的客户端连接列表用于存储所有连接的TCP客户端
初始化服务器状态为停止状态isServerRunning false
public partial class TcpServerForm : Form
{private TcpListener tcpListener;private Thread listenerThread;private ListTcpClient connectedClients;private bool isServerRunning false;public TcpServerForm(){InitializeComponent();connectedClients new ListTcpClient(); // 初始化客户端列表}
} 2. 启动服务器 btnStart_Click(object sender, EventArgs e) 详细流程
输入验证检查IP地址和端口号格式是否正确
启动监听创建TcpListener实例并调用Start()方法
线程创建创建后台线程专门处理客户端连接请求
UI更新禁用启动按钮启用停止和发送按钮更新状态标签
日志记录记录服务器启动成功信息
private void btnStart_Click(object sender, EventArgs e)
{try{// 验证IP地址输入if (!IPAddress.TryParse(txtIP.Text, out IPAddress ipAddress)){MessageBox.Show(请输入有效的IP地址);return;}// 验证端口号输入1-65535if (!int.TryParse(txtPort.Text, out int port) || port 1 || port 65535){MessageBox.Show(请输入有效的端口号(1-65535));return;}// 创建并启动TCP监听器tcpListener new TcpListener(ipAddress, port);tcpListener.Start();isServerRunning true;// 创建并启动监听线程listenerThread new Thread(new ThreadStart(ListenForClients));listenerThread.IsBackground true; // 设置为后台线程主程序退出时自动终止listenerThread.Start();// 更新UI控件状态btnStart.Enabled false;btnStop.Enabled true;btnSend.Enabled true;lblStatus.Text $服务器已启动 - {ipAddress}:{port};AddLog($服务器启动成功监听 {ipAddress}:{port});}catch (Exception ex){MessageBox.Show($启动服务器失败: {ex.Message});}
}
3. 停止服务器 StopServer() 关键技术点
lock关键字防止多线程同时访问connectedClients集合
Invoke方法确保跨线程UI更新的安全性
异常处理使用空catch块忽略关闭连接时的异常
private void StopServer()
{try{isServerRunning false; // 设置停止标志// 停止TCP监听器tcpListener?.Stop();// 线程安全地关闭所有客户端连接lock (connectedClients) // 使用lock确保线程安全{foreach (var client in connectedClients){try{client.Close(); // 关闭客户端连接}catch { } // 忽略关闭过程中的异常}connectedClients.Clear(); // 清空客户端列表}// 使用Invoke确保UI操作在UI线程上执行Invoke(new Action(() {btnStart.Enabled true;btnStop.Enabled false;btnSend.Enabled false;lblStatus.Text 服务器已停止;lstClients.Items.Clear(); // 清空客户端列表显示AddLog(服务器已停止);}));}catch (Exception ex){Invoke(new Action(() AddLog($停止服务器时出错: {ex.Message})));}
}
4. 客户端监听循环 ListenForClients() 重要特性
阻塞调用AcceptTcpClient()会阻塞线程直到有客户端连接
一客户一线程每个客户端连接都有独立的处理线程
实时UI更新新连接立即显示在界面上
private void ListenForClients()
{while (isServerRunning) // 主循环检查服务器运行状态{try{// 阻塞等待客户端连接同步方法TcpClient client tcpListener.AcceptTcpClient();// 为每个客户端创建独立的处理线程Thread clientThread new Thread(new ParameterizedThreadStart(HandleClientComm));clientThread.IsBackground true;clientThread.Start(client); // 将客户端对象传递给线程// 线程安全地添加客户端到列表lock (connectedClients){connectedClients.Add(client);}// 更新UI显示新连接的客户端Invoke(new Action(() {string clientInfo ${((IPEndPoint)client.Client.RemoteEndPoint).Address}:{((IPEndPoint)client.Client.RemoteEndPoint).Port};lstClients.Items.Add(clientInfo);AddLog($客户端连接: {clientInfo});}));}catch (Exception ex){if (isServerRunning) // 只有在服务器运行时才记录错误{Invoke(new Action(() AddLog($接受客户端连接时出错: {ex.Message})));}break; // 发生异常时退出循环}}
}
5. 客户端通信处理 HandleClientComm(object client) 数据处理流程
获取网络流通过GetStream()获取用于读写的数据流
循环读取持续读取客户端发送的数据
编码转换将字节数组转换为UTF-8字符串
异常处理处理网络中断等异常情况
资源清理在finally块中确保连接正确关闭
private void HandleClientComm(object client)
{TcpClient tcpClient (TcpClient)client;NetworkStream clientStream tcpClient.GetStream(); // 获取网络流byte[] buffer new byte[4096]; // 4KB接收缓冲区int bytesRead;try{while (isServerRunning tcpClient.Connected){// 阻塞读取客户端数据bytesRead clientStream.Read(buffer, 0, buffer.Length);if (bytesRead 0) // 连接已关闭break;// 将字节数据转换为字符串UTF-8编码string receivedData Encoding.UTF8.GetString(buffer, 0, bytesRead);// 在UI线程上更新接收到的消息Invoke(new Action(() {string clientInfo ${((IPEndPoint)tcpClient.Client.RemoteEndPoint).Address}:{((IPEndPoint)tcpClient.Client.RemoteEndPoint).Port};AddLog($来自 {clientInfo}: {receivedData});}));}}catch (Exception ex){if (isServerRunning){Invoke(new Action(() AddLog($处理客户端通信时出错: {ex.Message})));}}finally // 确保资源清理{// 从客户端列表中移除lock (connectedClients){connectedClients.Remove(tcpClient);}// 更新UI显示客户端断开Invoke(new Action(() {string clientInfo ${((IPEndPoint)tcpClient.Client.RemoteEndPoint).Address}:{((IPEndPoint)tcpClient.Client.RemoteEndPoint).Port};// 从列表框中移除客户端for (int i 0; i lstClients.Items.Count; i){if (lstClients.Items[i].ToString() clientInfo){lstClients.Items.RemoveAt(i);break;}}AddLog($客户端断开连接: {clientInfo});}));tcpClient.Close(); // 关闭客户端连接}
}
6. 消息发送 btnSend_Click(object sender, EventArgs e) 广播机制
遍历所有客户端向列表中的每个客户端发送相同消息
连接状态检查发送前验证客户端是否仍然连接
自动清理移除已断开连接的客户端
private void btnSend_Click(object sender, EventArgs e)
{if (string.IsNullOrWhiteSpace(txtSend.Text)){MessageBox.Show(请输入要发送的数据);return;}try{byte[] data Encoding.UTF8.GetBytes(txtSend.Text); // 字符串转字节数组lock (connectedClients){ListTcpClient disconnectedClients new ListTcpClient();foreach (var client in connectedClients){try{if (client.Connected){NetworkStream stream client.GetStream();stream.Write(data, 0, data.Length); // 发送数据stream.Flush(); // 立即发送缓冲区数据}else{disconnectedClients.Add(client); // 记录已断开的客户端}}catch{disconnectedClients.Add(client); // 记录发送失败的客户端}}// 清理已断开的客户端连接foreach (var disconnectedClient in disconnectedClients){connectedClients.Remove(disconnectedClient);disconnectedClient.Close();}}AddLog($发送到所有客户端: {txtSend.Text});txtSend.Clear(); // 清空发送文本框}catch (Exception ex){MessageBox.Show($发送数据失败: {ex.Message});}
}
7. 日志记录 AddLog(string message) 线程安全机制
InvokeRequired检测当前是否在非UI线程
Invoke将调用封送到UI线程执行
递归调用确保最终在UI线程上执行实际操作
private void AddLog(string message)
{if (txtReceive.InvokeRequired) // 检查是否需要在UI线程上执行{txtReceive.Invoke(new Actionstring(AddLog), message); // 递归调用}else{txtReceive.AppendText($[{DateTime.Now:HH:mm:ss}] {message}\r\n); // 添加时间戳txtReceive.ScrollToCaret(); // 自动滚动到最新内容}
}
8. 窗体关闭事件 OnFormClosing(FormClosingEventArgs e)
protected override void OnFormClosing(FormClosingEventArgs e)
{StopServer(); // 确保服务器正确停止base.OnFormClosing(e); // 调用基类方法
} 二、所有源码
TcpServerForm .Designer.cs界面代码 using System;
using System.Drawing;
using System.Windows.Forms;namespace TcpServerApp
{partial class TcpServerForm{/*/// summary/// Required designer variable./// /summaryprivate System.ComponentModel.IContainer components null;/// summary/// Clean up any resources being used./// /summary/// param namedisposingtrue if managed resources should be disposed; otherwise, false./paramprotected 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./// /summaryprivate void InitializeComponent(){this.components new System.ComponentModel.Container();this.AutoScaleMode System.Windows.Forms.AutoScaleMode.Font;this.ClientSize new System.Drawing.Size(800, 450);this.Text TcpServerForm;}#endregion*/private System.ComponentModel.IContainer components null;private TextBox txtIP;private TextBox txtPort;private Button btnStart;private Button btnStop;private TextBox txtSend;private Button btnSend;private TextBox txtReceive;private ListBox lstClients;private Label lblStatus;private Label label1;private Label label2;private Label label3;private Label label4;private Label label5;protected override void Dispose(bool disposing){if (disposing (components ! null)){components.Dispose();}base.Dispose(disposing);}private void InitializeComponent(){this.components new System.ComponentModel.Container();this.txtIP new TextBox();this.txtPort new TextBox();this.btnStart new Button();this.btnStop new Button();this.txtSend new TextBox();this.btnSend new Button();this.txtReceive new TextBox();this.lstClients new ListBox();this.lblStatus new Label();this.label1 new Label();this.label2 new Label();this.label3 new Label();this.label4 new Label();this.label5 new Label();// 窗体设置this.Text TCP服务器;this.Size new Size(800, 600);this.StartPosition FormStartPosition.CenterScreen;// IP标签和文本框this.label1.Location new Point(20, 20);this.label1.Size new Size(80, 20);this.label1.Text IP地址:;this.txtIP.Location new Point(100, 20);this.txtIP.Size new Size(150, 20);this.txtIP.Text 127.0.0.1;// 端口标签和文本框this.label2.Location new Point(270, 20);this.label2.Size new Size(80, 20);this.label2.Text 端口:;this.txtPort.Location new Point(320, 20);this.txtPort.Size new Size(80, 20);this.txtPort.Text 8080;// 启动按钮this.btnStart.Location new Point(420, 18);this.btnStart.Size new Size(80, 25);this.btnStart.Text 启动服务器;this.btnStart.Click new EventHandler(this.btnStart_Click);// 停止按钮this.btnStop.Location new Point(510, 18);this.btnStop.Size new Size(80, 25);this.btnStop.Text 停止服务器;this.btnStop.Enabled false;this.btnStop.Click new EventHandler(this.btnStop_Click);// 状态标签this.lblStatus.Location new Point(20, 60);this.lblStatus.Size new Size(400, 20);this.lblStatus.Text 服务器未启动;// 客户端列表标签和列表框this.label3.Location new Point(20, 100);this.label3.Size new Size(100, 20);this.label3.Text 已连接客户端:;this.lstClients.Location new Point(20, 120);this.lstClients.Size new Size(250, 200);// 接收数据标签和文本框this.label4.Location new Point(20, 340);this.label4.Size new Size(100, 20);this.label4.Text 接收数据:;this.txtReceive.Location new Point(20, 360);this.txtReceive.Multiline true;this.txtReceive.ScrollBars ScrollBars.Vertical;this.txtReceive.Size new Size(750, 100);this.txtReceive.ReadOnly true;// 发送数据标签和文本框this.label5.Location new Point(20, 480);this.label5.Size new Size(100, 20);this.label5.Text 发送数据:;this.txtSend.Location new Point(20, 500);this.txtSend.Multiline true;this.txtSend.ScrollBars ScrollBars.Vertical;this.txtSend.Size new Size(650, 50);// 发送按钮this.btnSend.Location new Point(680, 500);this.btnSend.Size new Size(90, 50);this.btnSend.Text 发送;this.btnSend.Enabled false;this.btnSend.Click new EventHandler(this.btnSend_Click);// 添加控件到窗体this.Controls.AddRange(new Control[] {this.txtIP, this.txtPort, this.btnStart, this.btnStop,this.txtSend, this.btnSend, this.txtReceive, this.lstClients,this.lblStatus, this.label1, this.label2, this.label3,this.label4, this.label5});}}
} TcpServerForm.cs源码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;using System.Net;
using System.Net.Sockets;using System.Threading;namespace TcpServerApp
{public partial class TcpServerForm : Form{private TcpListener tcpListener;private Thread listenerThread;private ListTcpClient connectedClients;private bool isServerRunning false;public TcpServerForm(){InitializeComponent();connectedClients new ListTcpClient();}private void btnStart_Click(object sender, EventArgs e){try{// 验证输入if (!IPAddress.TryParse(txtIP.Text, out IPAddress ipAddress)){MessageBox.Show(请输入有效的IP地址);return;}if (!int.TryParse(txtPort.Text, out int port) || port 1 || port 65535){MessageBox.Show(请输入有效的端口号(1-65535));return;}// 启动服务器tcpListener new TcpListener(ipAddress, port);tcpListener.Start();isServerRunning true;// 启动监听线程listenerThread new Thread(new ThreadStart(ListenForClients));listenerThread.IsBackground true;listenerThread.Start();// 更新UIbtnStart.Enabled false;btnStop.Enabled true;btnSend.Enabled true;lblStatus.Text $服务器已启动 - {ipAddress}:{port};AddLog($服务器启动成功监听 {ipAddress}:{port});}catch (Exception ex){MessageBox.Show($启动服务器失败: {ex.Message});}}private void btnStop_Click(object sender, EventArgs e){StopServer();}private void StopServer(){try{isServerRunning false;// 停止监听tcpListener?.Stop();// 断开所有客户端连接lock (connectedClients){foreach (var client in connectedClients){try{client.Close();}catch { }}connectedClients.Clear();}// 更新UIInvoke(new Action(() {btnStart.Enabled true;btnStop.Enabled false;btnSend.Enabled false;lblStatus.Text 服务器已停止;lstClients.Items.Clear();AddLog(服务器已停止);}));}catch (Exception ex){Invoke(new Action(() AddLog($停止服务器时出错: {ex.Message})));}}private void ListenForClients(){while (isServerRunning){try{// 接受客户端连接TcpClient client tcpListener.AcceptTcpClient();// 为新客户端创建处理线程Thread clientThread new Thread(new ParameterizedThreadStart(HandleClientComm));clientThread.IsBackground true;clientThread.Start(client);// 添加到客户端列表lock (connectedClients){connectedClients.Add(client);}// 更新UIInvoke(new Action(() {string clientInfo ${((IPEndPoint)client.Client.RemoteEndPoint).Address}:{((IPEndPoint)client.Client.RemoteEndPoint).Port};lstClients.Items.Add(clientInfo);AddLog($客户端连接: {clientInfo});}));}catch (Exception ex){if (isServerRunning){Invoke(new Action(() AddLog($接受客户端连接时出错: {ex.Message})));}break;}}}private void HandleClientComm(object client){TcpClient tcpClient (TcpClient)client;NetworkStream clientStream tcpClient.GetStream();byte[] buffer new byte[4096];int bytesRead;try{while (isServerRunning tcpClient.Connected){bytesRead clientStream.Read(buffer, 0, buffer.Length);if (bytesRead 0)break;string receivedData Encoding.UTF8.GetString(buffer, 0, bytesRead);// 更新UIInvoke(new Action(() {string clientInfo ${((IPEndPoint)tcpClient.Client.RemoteEndPoint).Address}:{((IPEndPoint)tcpClient.Client.RemoteEndPoint).Port};AddLog($来自 {clientInfo}: {receivedData});}));}}catch (Exception ex){if (isServerRunning){Invoke(new Action(() AddLog($处理客户端通信时出错: {ex.Message})));}}finally{// 客户端断开连接lock (connectedClients){connectedClients.Remove(tcpClient);}Invoke(new Action(() {string clientInfo ${((IPEndPoint)tcpClient.Client.RemoteEndPoint).Address}:{((IPEndPoint)tcpClient.Client.RemoteEndPoint).Port};// 从列表中移除for (int i 0; i lstClients.Items.Count; i){if (lstClients.Items[i].ToString() clientInfo){lstClients.Items.RemoveAt(i);break;}}AddLog($客户端断开连接: {clientInfo});}));tcpClient.Close();}}private void btnSend_Click(object sender, EventArgs e){if (string.IsNullOrWhiteSpace(txtSend.Text)){MessageBox.Show(请输入要发送的数据);return;}try{byte[] data Encoding.UTF8.GetBytes(txtSend.Text);lock (connectedClients){ListTcpClient disconnectedClients new ListTcpClient();foreach (var client in connectedClients){try{if (client.Connected){NetworkStream stream client.GetStream();stream.Write(data, 0, data.Length);stream.Flush();}else{disconnectedClients.Add(client);}}catch{disconnectedClients.Add(client);}}// 移除已断开的客户端foreach (var disconnectedClient in disconnectedClients){connectedClients.Remove(disconnectedClient);disconnectedClient.Close();}}AddLog($发送到所有客户端: {txtSend.Text});txtSend.Clear();}catch (Exception ex){MessageBox.Show($发送数据失败: {ex.Message});}}private void AddLog(string message){if (txtReceive.InvokeRequired){txtReceive.Invoke(new Actionstring(AddLog), message);}else{txtReceive.AppendText($[{DateTime.Now:HH:mm:ss}] {message}\r\n);txtReceive.ScrollToCaret();}}protected override void OnFormClosing(FormClosingEventArgs e){StopServer();base.OnFormClosing(e);}}
} 三、效果演示
使用网络调试助手进行调试设置好ip和端口验证接收数据和发送数据