c#软件开发学习笔记--TcpListener\TcpClient\UdpClient

(C#)TCP与UDP通信流程、Tcplistener和Tcpclient进行通信、UdpClient进行通信 1.基于Tcp协议的Socket通讯类似于B/S架构,面向连接,不同的是服务器端可以向客户端主动的推送消息 流程顺序。可靠性高 (1)建立一个套接字(Socket) (2)绑定服务器端IP地址及端口号-服务器端 (3)利用Listen()方法开启监听-服务器端 (4)利用Accept()方法等待客户端连接-服务器端 (5)Connect()方法与服务器端建立连接-客户端 (6)Sen... 阅读详情

TCP / UDP 设备连接学习总结


一、TcpListener —— 服务器端

 客户端                              服务器 (TcpListener)
   │                                       │
   │  ───① new TcpListener(ip, port)       │
   │  ───② .Start() 开始监听 ──────────     │
   │                                       │
   │  ◄─── AcceptTcpClientAsync() 阻塞等待  │
   │                                       │
   │  ───③ TcpClient.ConnectAsync()  ──►   │
   │                                       │
   │  ◄── 返回 TcpClient 实例 ─────────     │
   │                                       │
   │  ───④ GetStream() 获取 NetworkStream  │
   │                                       │
   │  ═════⑤ ReadAsync() / WriteAsync() ═══数据交换═════
   │                                       │
   │  ───⑥ 停止: Stop() 停止监听 ───────    │
   │                                       │

1.1 关键方法与属性

成员说明
new TcpListener(IPAddress, int port)构造,绑定本地 IP 与端口
Start()开始监听
Stop()停止监听
Pending()是否有挂起的连接请求(常用于循环里非阻塞判断)
AcceptTcpClient() / AcceptTcpClientAsync()同步/异步接受一个连接,返回 TcpClient
AcceptTcpClientAsync(CancellationToken)支持取消令牌的异步接受(.NET 9 项目中使用)

1.2 基础实现(TCPListen)

业务:TCP 服务器收到客户端数据 → 写入串口;串口返回数据 → 回发给当前客户端。使用 ConcurrentQueue 把多个客户端请求串行化,避免串口并发冲突。

// 启动监听
tcpListen = new TcpListener(IPAddress.Parse("192.168.219.14"), 9999);
tcpListen.Start();

// 异步循环接受连接
private void AcceptRequest()
{
    cts = new CancellationTokenSource();
    Task.Run(async () =>
    {
        while (!cts.IsCancellationRequested)
        {
            if (tcpListen == null) break;
            if (tcpListen.Pending()) continue;          // 若挂起连接则跳过
            TcpClient tcpClient = await tcpListen.AcceptTcpClientAsync();
            AcceptData(tcpClient);                       // 转入数据接收循环
        }
    }, cts.Token);
}

// 读取客户端数据并通过 NetworkStream 回写串口响应
NetworkStream stream = currentClient.GetStream();
stream.Write(fullFrame, 0, fullFrame.Length);

1.3 完整设备服务器实现(TCPListen连接设备服务器)

在基础版上增加了:配置持久化(FileIni)、本机 IP 自动识别、收发字节计数、Modbus 帧按功能码解析(0x03 读 / 0x06 写)、带 CancellationToken 的异步 API。

// 自动获取本机 IPv4 地址用于监听
IPAddress[] addresses = Dns.GetHostAddresses(Dns.GetHostName());
foreach (IPAddress address in addresses)
    if (address.AddressFamily == AddressFamily.InterNetwork)
        txtServerIP.Text = address.ToString();

// 启动
tcpListener = new TcpListener(IPAddress.Parse(txtServerIP.Text), int.Parse(txtPort.Text));
tcpListener.Start();

// 带取消令牌的异步接受
TcpClient client = await tcpListener.AcceptTcpClientAsync(_cts.Token);

// 带取消令牌的异步读取
NetworkStream stream = client.GetStream();
int len = await stream.ReadAsync(buffer, _cts.Token);
if (len <= 0) return;   // len==0 表示客户端已正常断开

// 回写响应(异步)
await stream.WriteAsync(fullFrame);

停止服务器时释放资源:

private void StopServer()
{
    _cts?.Cancel();
    serialPort?.Close();
    tcpListener?.Stop();   // 停止监听
    tcpListener = null;
}

二、TcpClient —— 客户端

 客户端 (TcpClient)                      服务器
   │                                       │
   │  ───① new TcpClient() ─────────────   │
   │                                       │
   │  ───② .ConnectAsync(host, port)  ─►   │  AcceptTcpClientAsync()
   │                                       │
   │  ◄── 连接成功 (Connected=true)  ────   │
   │                                       │
   │  ───③ GetStream() 获取 NetworkStream  │
   │                                       │
   │  ───④ Write() / WriteAsync() 发送 ──► │  ReadAsync() 接收
   │                                       │
   │  ◄──⑤ ReadAsync() 接收响应  ─────────  │  WriteAsync() 回写
   │                                       │
   │  ═════ 循环收发 ═══════════════════    │
   │                                       │
   │  ───⑥ 停止: Close() 关闭连接 ──────    │
   │                                       │

2.1 关键方法与属性

成员说明
new TcpClient()构造一个未连接的客户端
Connect(host, port) / ConnectAsync(host, port)同步/异步连接服务器
Connected (bool)当前是否处于连接状态
Available (int)网络缓冲区中可读字节数
GetStream()返回 NetworkStream 用于读写
Client (Socket)底层 Socket,可取 RemoteEndPoint 等信息
Close()关闭连接

NetworkStream 关键成员:Read / ReadAsync(返回 0 表示对端关闭)、Write / WriteAsync。

2.2 基础实现(TCPClient)

业务:连接服务器 → 后台循环接收 → 定时器周期性发送。

// 连接
private async Task ConnectServer()
{
    tcpClient = new TcpClient();
    await tcpClient.ConnectAsync("192.168.219.14", 9999);
}

// 接收循环:Available 判断 + ReadAsync
private void AcceptData()
{
    cts = new CancellationTokenSource();
    Task.Run(async () =>
    {
        byte[] buffer = new byte[1024];
        while (!cts.IsCancellationRequested)
        {
            if (tcpClient == null || !tcpClient.Connected) continue;
            NetworkStream stream = tcpClient.GetStream();
            int len = await stream.ReadAsync(buffer, 0, buffer.Length, cts.Token);
            if (len <= 0) break;
            // 处理 buffer[0..len)
        }
    }, cts.Token);
}

// 发送
NetworkStream stream = tcpClient.GetStream();
byte[] bs = Encoding.UTF8.GetBytes(textBox1.Text);
stream.Write(bs, 0, bs.Length);

2.3 设备客户端实现(TCPClient连接设备客户端)

业务:通过 TCP 承载 Modbus RTU 协议——组装请求帧(功能码 0x03 读 / 0x06 写)+ CRCHelper.CRC16 校验,发送后解析响应。发送使用 lock(sendLock) 保证线程安全。

// 连接(含异常提示)
await client.ConnectAsync(txtServerIP.Text, int.Parse(txtPort.Text));

// 发送 Modbus 读保持寄存器请求(功能码 0x03)
private void SendRequest(ushort slaveAddress, ushort startAddress, ushort dataLength)
{
    lock (sendLock)
    {
        if (client == null) return;
        byte[] bs = new byte[8];
        bs[0] = (byte)slaveAddress;
        bs[1] = 0X03;
        bs[2] = (byte)(startAddress >> 8);
        bs[3] = (byte)(startAddress & 0XFF);
        bs[4] = (byte)(dataLength >> 8);
        bs[5] = (byte)(dataLength & 0XFF);
        byte[] crc = CRCHelper.CRC16(bs);
        bs[6] = crc[0]; bs[7] = crc[1];

        client.GetStream().Write(bs);
    }
}

// 接收并按功能码解析响应
int funcCode = buffer[1];
if (funcCode == 0X03) { /* 解析寄存器值 */ }
else if (funcCode == 0X06) { /* 解析写入回显 */ }

断开连接:

private void DisConnectServer()
{
    _cts?.Cancel();
    client?.Close();
    client = null;
}

三、UdpClient —— 无连接收发

 客户端 (UdpClient)                      服务器 (UdpClient)
   │                                       │
   │  ───① new UdpClient(任意端口)          │
   │                                       │
   │  ───② 构造 IPEndPoint(server, port)   │
   │                                       │
   │  ───③ Send(data, len, endPoint)  ─►   │  ReceiveAsync() 阻塞等待
   │                                       │
   │                                       │  获得 RemoteEndPoint
   │                                       │
   │  ◄──④ ReceiveAsync() 收到响应  ─────   │  Send(data, len, remoteEndPoint)
   │                                       │
   │                                       │
   │  ═════ 无需连接,直接数据报收发 ════    │
   │                                       │
   │  ───⑤ 停止: Close() / Dispose() ───   │
   │                                       │

UDP 不需要建立连接,服务器与客户端的区别仅在于:服务器绑定固定端口并 ReceiveAsync 等待数据;客户端绑定任意端口(IPAddress.Any, 0)后用 Send 指定目标端点。

3.1 关键方法与属性

成员说明
new UdpClient(IPEndPoint)构造并绑定本地端点
Send(byte[], int, IPEndPoint)向指定远程端点发送数据报
ReceiveAsync()异步接收,返回 UdpReceiveResult(含 Buffer 与 RemoteEndPoint)
Close() / Dispose()释放资源

3.2 UDP 客户端

业务:向设备发送 Modbus 请求帧,异步接收并解析响应寄存器值。

// 绑定本地任意端口,目标端点由 endPoint 指定
client = new UdpClient(new IPEndPoint(IPAddress.Any, 0));
endPoint = new IPEndPoint(IPAddress.Parse(txtIp.Text), int.Parse(txtPort.Text));

// 发送
client.Send(bytes, bytes.Length, endPoint);

// 异步接收
var res = await client.ReceiveAsync();
if (res.Buffer[1] != 0X03) continue;
int byteCount = res.Buffer[2];
// 解析寄存器值...

3.3 UDP 服务器

业务:UDP 服务器收到客户端请求 → 写串口 → 串口返回数据 → 用 Send 回发给该客户端 RemoteEndPoint。同样用 ConcurrentQueue 串行化串口访问。

// 绑定本机 IP + 9999 端口
server = new UdpClient(new IPEndPoint(address, 9999));

// 接收循环
var res = await server.ReceiveAsync();
requestQueue.Enqueue(new RequestItem { clientEndPoint = res.RemoteEndPoint, data = res.Buffer });

// 串口响应回发给对应客户端
server.Send(fullFrame, fullFrame.Length, currentRequest.clientEndPoint);

四、通用设计模式总结

4.1 异步接收循环(统一范式)

所有子项目都采用相同范式:CancellationTokenSource + Task.Run + while(!cts.IsCancellationRequested) 循环 + await XxxAsync(cts.Token)。这是 WinForms 下避免阻塞 UI 线程的标准做法。

4.2 请求队列 + 串行化处理

串口是独占资源,不能并发写入。服务器端统一使用 ConcurrentQueue<RequestItem> + lock + isProcessing 标志位,把并发的网络请求排成队列,逐个转发给串口,串口响应完成后再出队下一个:

private void TryProcessQueue()
{
    lock (processLock)
    {
        if (isProcessing) return;
        if (requestQueue.IsEmpty) return;
        if (requestQueue.TryDequeue(out var item))
        {
            currentClient = item;
            isProcessing = true;
            serialPort.Write(item.Data, 0, item.Data.Length);
        }
    }
}

4.3 网口 ↔ 串口协议转换

以上这三个服务器项目的本质都是 协议网关:把以太网(TCP/UDP)上收到的 Modbus RTU 帧透传给串口设备,再把串口返回的帧回发给发起请求的网络客户端。

4.4 Modbus RTU 帧解析

按功能码确定帧长度,从 List<byte> 缓冲区中切片取完整帧:

  • 功能码 0x03(读):帧长 = 3 + 字节数 + 2(CRC)
  • 功能码 0x06(写):固定 8 字节
  • 帧尾 2 字节 CRC16(CRCHelper.CRC16)

完整帧解析实现(以串口数据接收为例):

private void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
    if (serialPort == null || !serialPort.IsOpen) return;

    // 读取串口缓冲区全部数据
    byte[] buffer = new byte[serialPort.BytesToRead];
    serialPort.Read(buffer, 0, buffer.Length);
    list.AddRange(buffer);

    // 循环处理缓冲区中可能存在的多个完整帧
    while (list.Count > 5)
    {
        // 根据功能码计算帧长度
        int funcCode = list[1];
        int fullFrameLength = 0;

        if (funcCode == 0X03)          // 读寄存器响应
        {
            int len = list[2];           // 字节数
            fullFrameLength = 3 + len + 2; // 地址 + 功能码 + 字节数 + 数据 + CRC
        }
        else if (funcCode == 0X06)     // 写单寄存器响应
        {
            fullFrameLength = 8;         // 固定 8 字节
        }

        // 缓冲区长度足够一个完整帧
        if (list.Count >= fullFrameLength)
        {
            byte[] fullFrame = list.Take(fullFrameLength).ToArray();
            list.RemoveRange(0, fullFrameLength);

            // 将完整帧回发给发起请求的客户端
            if (currentClient != null && currentClient.TcpClient != null &&
                currentClient.TcpClient.Connected)
            {
                NetworkStream stream = currentClient.TcpClient.GetStream();
                await stream.WriteAsync(fullFrame);
            }
        }
        else
            break;                       // 数据不足,等待更多字节
    }
}

4.5 连接状态与生命周期管理

  • 接受端:AcceptTcpClientAsync 返回的 TcpClient 用 Connected 判断活性,ReadAsync 返回 0 视为断开。
  • 停止:统一先 cts.Cancel() 取消后台任务,再 Close()/Stop()/Dispose() 释放网络与串口资源,并把对象置 null。
  • 客户端发送:用 lock 保护 NetworkStream.Write,避免定时器与按钮并发发送互相踩踏。

五、关键方法/属性速查表

类方法/属性用途出现子项目
TcpListenerStart() / Stop()启停监听TCPListen、TCPListen连接设备服务器
TcpListenerPending()是否有挂起连接TCPListen、TCPListen连接设备服务器
TcpListenerAcceptTcpClientAsync(CancellationToken)异步接受连接同上
TcpClientConnectAsync(host, port)异步连接服务器TCPClient、TCPClientTest、TCPClient连接设备客户端
TcpClientConnected / Available连接状态 / 可读字节全部 TCP 客户端
TcpClientGetStream()获取 NetworkStream全部 TCP
TcpClientClose()关闭连接全部 TCP
NetworkStreamReadAsync(buf, token)异步读(返回 0=断开)全部 TCP
NetworkStreamWrite(buf) / WriteAsync(buf)同步/异步写全部 TCP
UdpClientnew UdpClient(IPEndPoint)绑定本地端点WindowsFormsApp5/6
UdpClientSend(buf, len, IPEndPoint)发送到指定端点WindowsFormsApp5/6
UdpClientReceiveAsync()异步接收(含来源端点)WindowsFormsApp5/6
UdpClientClose() / Dispose()释放资源WindowsFormsApp5/6

六、对比与要点

6.1 TCP vs UDP

维度TCP(TcpListener / TcpClient)UDP(UdpClient)
连接面向连接,需 Accept/Connect无连接,直接 Send/Receive
可靠性可靠传输、保序不可靠、可能丢包/乱序
服务器区分TcpListener 监听 + TcpClient 表示每个连接仅 UdpClient,靠 RemoteEndPoint 区分客户端
数据流NetworkStream 读写流数据报 Send/ReceiveAsync
适用需要稳定可靠的设备控制(Modbus TCP)简单查询/广播/低开销场景

6.2 同步 vs 异步

  • 项目统一采用 异步 API(XxxAsync + await),配合 CancellationToken 实现可控停止,避免阻塞 WinForms UI 线程。
  • Pending() + continue 是一种轻量的非阻塞轮询写法,但更推荐直接 await AcceptTcpClientAsync(cts.Token)。

6.3 .NET 9 vs .NET Framework 4.8 差异

  • .NET 9 项目(date87 下 TCP 系列)可使用 AcceptTcpClientAsync(CancellationToken)、ReadAsync(buffer, token) 等带取消令牌的重载。
  • .NET Framework 4.8 项目(date84 下 UDP 系列)使用 ReceiveAsync()(无取消令牌重载),停止时靠 cts 循环判断 + Close() 触发异常退出循环。

七、学习要点清单

  1. 服务器三步走:new TcpListener(ip, port) → Start() → AcceptTcpClientAsync()。
  2. 客户端两步走:new TcpClient() → ConnectAsync(host, port),再用 GetStream() 读写。
  3. ReadAsync 返回 0 是判断对端正常关闭的关键信号。
  4. Available 属性可用于接收循环中避免空转,但异步 ReadAsync 本身会阻塞至有数据,二者择一即可。
  5. UDP 服务器与客户端本质相同,区别仅在绑定端点是否固定、是否主动 Send。
  6. 串口 + 网口混合场景下,务必用队列 + 锁串行化串口访问。
  7. 停止流程要有序:Cancel() 取消任务 → Close()/Stop() 关闭资源 → 置 null。
  8. Modbus RTU 帧需按功能码计算帧长并校验 CRC16,TCP 承载时帧边界由 ReadAsync 返回长度保证,UDP 则由数据报天然保界。
C#成魔之路<14> 网络编程技术(2 )System.Net.Sockets命名空间 System.Net.Sockets命名空间主要是提供制作Sockets网络应用程序的相关类,其中Socket类,TcpClient类、TcpListener类、UdpClient类较为常用,下面对其进行介绍1、Socket类 Socket类为网络通信提供了一套丰富的方法和属性,主要用于管理连接,实现Berkelery通信段套接字接口,同时,还定义了绑定、连接网络端点以及传输数据所需的各种方法,并 阅读详情

相关推荐

C#实现局域网P2P文件传输系统:高并发分发模型

P2P文件传输是一种去中心化的网络通信范式,其核心原理是通过节点间动态协作实现流式复制与带宽聚合,突破传统客户端-服务器架构的单点带宽瓶颈。该技术具备低延迟、抗单点故障、免公网依赖等显著工程价值,广泛应用于工业固件升级、教育软件部署、内网大文件分发等局域网高并发场景。基于C#实现的轻量级P2P模型,依托.NET原生Socket API与async/await异步模型,在Windows企业环境中具备极佳的部署兼容性与调试友好性;结合UDP广播发现、1MB分块策略、TCP KeepAlive调优及UPnP穿透等

dianlu5775的博客 425

TcpListener类与TcpClient类的使用

TcpListener和TcpClient类是对Socket的进一步封装,为基于TCP协议的网络通信提供更加便捷的调用方式。 TcpListener在服务器负责监听和接受客户端的连接请求,TcpClient类提供一系列可用于TCP网络通信的API,是以流的方式来读写数据的,调用GetStream的方法会发挥一个NetworkStream实例,即可发送和接收数据。 C#的TcpListe

da_xiang的博客 9551

C#上位机开发完整学习路径:从串口通信到PLC实战

上位机开发是工业自动化中连接设备与操作人员的核心环节,其本质并非单纯的界面设计,而是基于通信链路的数据采集与指令下发。通过串口、Socket或工业协议(如西门子PLC通信),上位机需要完成数据解析、协议校验与实时控制,同时保证界面流畅不卡顿。在C#/.NET生态下,利用委托、事件和异步编程可有效解决UI刷新与数据采集的并发问题,而合理的数据存储方案能支撑CSV大数据的稳定读写。从扫码枪触发到BMS电池监控,这些具体应用场景都对开发者的协议解析与工程调试能力提出高要求。本文梳理C#上位机开发的完整技能地图,涵

weixin_34315485的博客 433

c#socket 、TCPClient、TCPListener用法详解

c#socket 、TCPClient、TCPListener用法详解   Visual C#.Net网络程序开发-Socket篇 Microsoft.NetFramework为应用程序访问Internet提供了分层的、可扩展的以及受管辖的网络服务,其名字空间System.Net和System.Net.Sockets包含丰富的类可以开发多种网络应用程序。.Net类采用的分层结构允许应用程序在

涛哥向上专栏 4325

Unity+ASP.NET Socket联机游戏开发实战指南

TCP socket是实时多人游戏网络通信的底层基石,其核心在于连接管理、字节流处理、跨平台序列化与线程协同。理解粘包/半包原理、心跳保活机制、二进制协议设计及Unity主线程与Socket异步IO的桥接方式,是构建稳定联机逻辑的前提。这类技术广泛应用于局域网对战、教育VR、轻量MMO原型验证等场景,尤其适合需规避Photon/Mirror黑盒、直面网络本质的Unity开发者。本文以可运行的ASP.NET+Unity Socket联机Demo为载体,深入拆解从‘能连上’到‘连得稳’的关键七道工程坎。

weixin_34195142的博客 365

ANSYS 2022R2 安装教程:系统准备、许可证配置与故障排查

ANSYS 是面向工程仿真的多物理场商业软件平台,其安装远非普通应用软件的图形化向导流程,而涉及操作系统版本、运行库精确版本、硬件虚拟化支持、许可证服务架构等系统级配置。理解 ANSYS License Manager 的服务机制与端口依赖、掌握 Visual C++ 和 .NET Framework 的启用逻辑,是保障 Fluent、Mechanical、HFSS 等求解器稳定调用的基础。该技术栈广泛应用于高校教学、航空航天结构分析、电子设备电磁兼容仿真等场景。本指南聚焦 ANSYS 2022R2 版本在

weixin_28559803的博客 598

.NET 网络编程 TCPClient 、 TCPListener 、 Socket 、 UdpClient

再继续进行之前,我们假设客户端可以发送多条消息,而服务端要不断的接收来自客户端发送的消息,但是上面的代码只能接收客户端发来的一条消息,因为它已经输出了“输入Q键退出”,说明程序已经执行完毕,无法再进行任何动作。本章的所有操作都是同步操作,像上面的代码也只是作为一个入门的范例,实际当中,一个服务端只能为一个客户端提供服务的情况是不存在的,下面就让我们来看看上面所说的第四种情况,如何进行异步的服务端编程。我们接着再进行进一步处理,服务端将收到的字符串改为大写,然后回发,客户端接收后打印。

Kaizen的博客 1671

14、X射线图像处理与特征提取全解析

本文全面解析了X射线图像处理与特征提取的关键技术,涵盖图像预处理、滤波、边缘检测、分割与恢复等流程,并深入探讨了几何特征(如面积、周长、圆度、椭圆拟合)、强度特征(均值、方差、对比度)、傅里叶描述符、不变矩(Hu矩、Gupta矩)以及局部描述符(SIFT、SURF)和稀疏表示方法。同时介绍了特征选择的过滤法、包装法和嵌入法,并结合Matlab代码示例展示了各类特征的实际提取过程。文章最后总结了当前技术的应用现状,并展望了深度学习在X射线图像分析中的未来潜力。

pz89012345的博客 134

C# 上位机UDP/TCP连接外部设备

UDP(无连接协议)与TCP(三次握手连接状态)不同,UDP的通信双方平等,没有服务端、客户端之分,且UDP通信可以广播,而TCP作为点对点协议,必须先建立连接,因此先用UDP广播获取外部设备IP。目标:上位机读取自身网卡信息,按照已知的外部设备IP,修正网卡自身IP,实现同一网段,再建立TCP连接;连接方式:PC与外部设备通过网线直连,此时PC端需调整IP,让自身与外部设备在同一网段下;目标:通过UPD探测外部连接设备,获取外部设备的IP,再根据IP建立TCP链接;三、 建立TCP连接。

HikiHachi的博客 237

Android 埋点信息分析——statsd框架

StatsPullAtomService 用以采集数据,并将数据填充到参数中,在StatsManager.PullAtomCallbackInternal 中会转换成 Parcel 格式传入到 native。 StatsCallbackPuller::PullInternal 中会回调StatsManager.PullAtomCallbackInternal 的onPullAtom,该函数中会回调StatsCallbackPuller::PullInternal 中定义的PullResultRecei

私房菜 2630

Open3D 使用RANSAC分割平面【2026最新版】

使用RANSAC从点云中分割平面,用segement_plane函数。博客长期更新,本文最新更新时间为:2026年2月28日。

点云侠的博客 37万+

C#高级知识

创建了Thread类的对象之后,线程对象已存在并已配置,但并未创建实际的线程,这时,只有在调用Start()方法后,才会创建实际的线程。Abort(object stateInfo)终止线程,在调用此方法的线程上引发ThreadAbortException异常,以开始终止此线程并提供有关线程终止的异常信息的过程.stateInfo对象包含了应用程序特定的信息(如状态),该信息可供正被终止的线程使用。调用Suspend()方法挂起线程时,.NET通常会允许该线程再执行几个指令,以达到线程可以安全挂起的状态。

chenglin016的博客 1413

12、有杆泵抽油系统:原理、性能与选择

本文全面介绍了有杆泵抽油系统的原理、性能分析和设备选择方法。有杆泵抽油系统广泛应用于石油开采领域,通过地面抽油装置与井下柱塞泵的配合,实现高效、稳定的原油提升。文章详细解析了系统的工作原理、组成结构、光杆运动特性、载荷计算、泵输送能力及功率需求,并提供了抽油装置的选择流程和实际案例分析。此外,还探讨了泵的容积效率影响因素、示功图的作用及系统优化运行的建议,为石油开采工程提供了理论支持和实践指导。

gan8painter的博客 435

【C#入门】Day25-Day29 完整知识点归纳总结

本文是 C# 入门系列第六部分(进阶专题)的完整内容,涵盖网络编程、委托与事件、异步编程、LINQ 查询以及一个综合项目实战。通过五天学习,读者将从单机编程迈向网络通信与高级语言特性,最终完成一个具备网络通信功能的桌面聊天程序(MyQQ)。

2301_80444089的博客 218

4.Simulink基础建模操作——加减乘除运算

加减乘除运算

FPGA/MATLAB学习教程/源码/项目合作开发 9550

HENU 2024年C#网络应用编程核心实战技巧与期末速查指南

本文为HENU学子提供了C#网络应用编程的期末速查指南,涵盖网络编程基础、多线程并发、TCP/UDP实战及ASP.NET Core核心开发。文章深入解析了IP地址、数据流、TcpListener、TcpClient、UdpClient等关键类,并重点探讨了TCP粘包、异步编程、线程同步等高频考点与实战技巧,旨在帮助学生高效复习并掌握核心实战技能。

weixin_29228781的博客 181

避坑指南:新手爬百度图片3个致命错,改完批量保存本地(亲测有效)

新手爬百度图片的核心是“绕开静态HTML,抓准API接口+处理反爬+提取原图”,改完本文提到的3个核心错,就能稳定批量保存高清图片。这套思路可复用在其他图片网站(如必应图片、360图片),只需修改API接口和参数即可。如果想进一步优化,可添加代理IP池、多线程下载(新手不建议,容易触发反爬)、图片去重等功能!

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 1587

C#与Unity构建工业设备仿真系统:从模型驱动到数字孪生

设备仿真是工业自动化与数字孪生领域的核心技术,它通过软件模拟真实设备的运行状态与行为逻辑,为方案验证、操作培训与算法测试提供安全、高效的虚拟环境。其核心原理在于建立物理设备与虚拟模型之间的数据映射与状态同步。在技术实现上,C#凭借其强大的生态与.NET框架,常被用于开发上位机通信与逻辑控制模块;而Unity引擎则以其卓越的实时3D渲染与交互能力,成为构建高保真可视化界面的理想选择。两者的结合,能够高效打通从数据采集、协议解析到3D驱动的全链路,实现虚实同步。这一技术组合尤其适用于需要直观交互与沉浸式体验的工

weixin_33849215的博客 431

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

C#学习路线与工程实践:从语法基础到上位机开发

C#是一门集类型安全、面向对象与异步编程于一体的通用语言,其核心在于理解值类型与引用类型的内存语义、字符串与集合的高效处理,以及LINQ带来的声明式数据操作能力。在工程实践中,HttpClient与async/await解决了网络通信中的并发与阻塞问题,而特性与反射则支撑起框架级扩展。面向工业自动化场景,上位机开发成为C#的热门应用方向,常涉及串口通信、Modbus协议解析以及西门子1200等PLC的数据交互,同时海康视频流接入也考验着开发者对SDK与多线程的掌控。文章基于高频搜索关键词,梳理从语法基础到上

weixin_33857679的博客 260

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

第6章第4节:自定义分词器

本节详解Elasticsearch自定义分词器,解析analyzer三段式结构(char_filter→tokenizer→filter),掌握常用组件如ik_max_word、synonym_graph、ngram等。通过_analyze API调试分词效果,实现“索引时扩展同义词、搜索时不带”的生产级方案,提升中文搜索与智能提示体验。

啊渊的专栏 782

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

C#使用opencv和Yolo模型识别车牌号

本文基于OpenCVSharp与OnnxRuntime,结合YoloV8n-pose_plate模型(检测车牌位置)和OCR模型(识别车牌文字),实现高效车牌识别。通过预处理、目标检测、NMS筛选及文字识别流程,最终输出车牌框位置与识别文本。代码封装良好,支持自定义路径与置信度阈值,具备实际应用价值。

lweiyue的专栏 185

C# NAFNet 图片去模糊

基于NAFNet与ONNX Runtime的C# WinForms图片去模糊工具,支持DirectML GPU加速与CPU回退,实现一键去模糊、大图分块处理、并排对比及拖拽打开。具备高DPI适配、自绘圆角界面、命令行批量处理等功能,适用于Windows 10/11系统,可灵活配置模型路径与分块大小,解决显存不足与边缘接缝问题。

hixiong123的博客 263

使用C#代码提取、修改或删除 Excel 中的超链接

通过 C# 和 VB.NET,可以方便地管理 Excel 文件中的超链接,包括提取、修改和删除等操作。提取超链接: 获取工作表中的超链接集合,读取每个超链接的地址和类型,并将相关信息保存到文本文件中。修改超链接: 更新超链接的显示文本和目标地址,确保链接信息准确。删除超链接: 移除指定的超链接,同时可以选择保留单元格中的原有显示文本,或清除单元格的全部内容。这些操作可以帮助开发人员更高效地管理 Excel 文档中的链接信息,减少重复的手动操作,也便于在数据迁移、文档维护和自动化报表处理等场景中使用。

2501_93070778的博客 238

C#: 控件不支持透明的背景色

把透明度固定为255。

海天鹰 49

基于 OPC UA 的半导体工厂化学气体传输 SCADA 监控系统:架构设计与 C# MVVM 实现

本文提出一套面向半导体化学气体传输的可演进SCADA系统,基于OPCUA统一信息模型与C#+WPF+MVVM技术栈,实现从气源到机台的全链路实时监控、安全联锁与追溯。通过资产树建模、分层解耦架构与标准对齐(SEMI E30/E95/S2),确保系统可扩展、可维护、可审计,满足高安全、高可靠要求,支持快速落地与持续演进。

ponygame的博客 336
上一篇: c#软件开发学习笔记--网络通讯、TCP、Socket
下一篇: c#软件开发学习笔记--Modbus-TCP/UDP网口通讯
Z599817841
博客等级 码龄4年 12粉丝 41原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值