手机通过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 服务器端实现
- 先安装NuGet包:
Microsoft.AspNetCore和Microsoft.AspNetCore.Mvc - 启动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
相关产品推荐
相关产品推荐

