You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

手机通过WiFi向C# WinForm应用传输扫码数据实现方案咨询

实现手机与C# WinForm的局域网WiFi数据传输方案

要实现同一局域网内手机与C# WinForm的数据传输,结合你的需求(传输数字单号、触发UI展示操作),推荐两种实用方案:


方案一:TCP Socket 通信(WinForm作为服务器)

这种方案适合低延迟的实时数据传输,WinForm作为TCP服务器监听指定端口,手机作为客户端连接并发送单号。

C# WinForm 服务器端实现

在主窗体中启动Socket监听(需放在后台线程避免阻塞UI):

using System.Net;
using System.Net.Sockets;
using System.Text;

private Socket _serverSocket;

// 窗体加载时启动监听
private void MainForm_Load(object sender, EventArgs e)
{
    StartTcpServer();
}

private void StartTcpServer()
{
    // 绑定本机所有IP的8888端口
    var endPoint = new IPEndPoint(IPAddress.Any, 8888);
    _serverSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
    
    _serverSocket.Bind(endPoint);
    _serverSocket.Listen(10);
    // 异步接受客户端连接
    _serverSocket.BeginAccept(AcceptClientCallback, null);
}

private void AcceptClientCallback(IAsyncResult ar)
{
    try
    {
        var clientSocket = _serverSocket.EndAccept(ar);
        // 继续监听下一个连接
        _serverSocket.BeginAccept(AcceptClientCallback, null);

        // 接收手机发送的单号
        byte[] buffer = new byte[1024];
        int receivedBytes = clientSocket.Receive(buffer);
        string orderNumber = Encoding.UTF8.GetString(buffer, 0, receivedBytes).Trim();

        // 切换到UI线程处理数据(必须,否则会触发跨线程UI操作异常)
        this.Invoke(new Action(() => ShowOrderDetail(orderNumber)));

        clientSocket.Close();
    }
    catch (Exception ex)
    {
        // 可添加日志记录或错误提示
    }
}

// 查询数据库并打开详情窗体
private void ShowOrderDetail(string orderNumber)
{
    // 替换为你的实际数据库查询逻辑
    var orderData = QueryOrderFromDatabase(orderNumber);
    
    if (orderData != null)
    {
        var detailForm = new OrderDetailForm(orderData);
        detailForm.Show();
    }
}

// 示例数据库查询方法
private OrderModel QueryOrderFromDatabase(string orderNumber)
{
    // 这里用伪代码示例,实际根据你的数据库类型(SQL Server/MySQL等)实现
    using (var conn = new SqlConnection("你的数据库连接字符串"))
    {
        conn.Open();
        var cmd = new SqlCommand("SELECT * FROM Orders WHERE OrderNumber = @Number", conn);
        cmd.Parameters.AddWithValue("@Number", orderNumber);
        // 读取数据并映射到OrderModel对象
        // ...
    }
}

// 窗体关闭时释放Socket资源
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
    _serverSocket?.Close();
}

手机端实现(以Android为例)

扫描二维码获取单号后,通过Socket连接WinForm服务器:

// 假设已获取到扫描后的单号orderNumber
String serverIp = "192.168.1.105"; // WinForm所在电脑的局域网IP
int port = 8888;

// 开启子线程执行网络操作(Android不允许主线程发网络请求)
new Thread(() -> {
    try {
        Socket socket = new Socket(serverIp, port);
        OutputStream outputStream = socket.getOutputStream();
        outputStream.write(orderNumber.getBytes("UTF-8"));
        outputStream.flush();
        socket.close();
    } catch (IOException e) {
        // 提示用户连接失败(比如弹Toast)
        runOnUiThread(() -> Toast.makeText(this, "连接服务器失败", Toast.LENGTH_SHORT).show());
    }
}).start();

方案二:HTTP轻量服务(WinForm内嵌Web服务器)

这种方案更简单,无需处理Socket细节,利用ASP.NET Core搭建迷你Web服务,手机通过POST请求发送单号。

C# WinForm 服务器端实现

  1. 先安装NuGet包:Microsoft.AspNetCore 和 Microsoft.AspNetCore.Mvc
  2. 启动Web服务:
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;

private IWebHost _webHost;

private void StartHttpServer()
{
    _webHost = new WebHostBuilder()
        .UseKestrel()
        .UseUrls("http://*:8080") // 监听所有IP的8080端口
        .ConfigureServices(services => services.AddMvc())
        .Configure(app => app.UseMvc(routes =>
        {
            routes.MapRoute(
                name: "default",
                template: "{controller=Order}/{action=Receive}");
        }))
        .Build();

    _webHost.Start();
}

// 定义处理请求的Controller
public class OrderController : Controller
{
    [HttpPost]
    public IActionResult Receive([FromBody] string orderNumber)
    {
        if (!string.IsNullOrWhiteSpace(orderNumber))
        {
            // 调用主窗体的UI处理方法
            Program.MainForm.Invoke(new Action(() => Program.MainForm.ShowOrderDetail(orderNumber)));
            return Ok("单号已接收");
        }
        return BadRequest("无效单号");
    }
}

// 在Program类中暴露主窗体实例,方便Controller调用
public static class Program
{
    public static MainForm MainForm;

    [STAThread]
    static void Main()
    {
        Application.SetHighDpiMode(HighDpiMode.SystemAware);
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        MainForm = new MainForm();
        Application.Run(MainForm);
    }
}

// 窗体关闭时停止Web服务
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
    _webHost?.StopAsync().Wait();
}

手机端实现

通过POST请求发送单号到WinForm的Web服务:

// 假设已获取到单号orderNumber
String serverUrl = "http://192.168.1.105:8080/Order/Receive";

OkHttpClient client = new OkHttpClient();
RequestBody body = RequestBody.create(MediaType.parse("text/plain"), orderNumber);
Request request = new Request.Builder()
        .url(serverUrl)
        .post(body)
        .build();

client.newCall(request).enqueue(new Callback() {
    @Override
    public void onFailure(Call call, IOException e) {
        runOnUiThread(() -> Toast.makeText(MainActivity.this, "请求失败", Toast.LENGTH_SHORT).show());
    }

    @Override
    public void onResponse(Call call, Response response) throws IOException {
        if (response.isSuccessful()) {
            runOnUiThread(() -> Toast.makeText(MainActivity.this, "发送成功", Toast.LENGTH_SHORT).show());
        }
    }
});

关键注意事项

  • 局域网IP获取:WinForm所在电脑的局域网IP可通过Dns.GetHostEntry(Dns.GetHostName()).AddressList获取,或在系统网络设置中查看,手机必须与电脑处于同一WiFi网络。
  • 防火墙设置:确保电脑防火墙允许指定端口(如8888、8080)的入站连接,否则手机无法访问。
  • UI线程切换:所有修改UI的操作必须通过Control.Invoke切换到UI线程执行,避免跨线程异常。
  • 二维码扫描:手机端可使用ZXing等成熟库实现二维码扫描,核心是提取扫描后的数字字符串。

内容的提问来源于stack exchange,提问作者Celestyn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 23:55:35