gpt4 book ai didi

c# - 为什么 System.IO.Ports.SerialPort.DataReceived 事件在调制解调器处于数据模式时不触发?

转载 作者:行者123 更新时间:2023-11-30 21:03:27 31 4
gpt4 key购买 nike

目前在我的大学里,我们正在这些旧的 56k 调制解调器之间进行通信。当从 PC 到调制解调器的消息通过串行端口时,我想使用 System.IO.Ports.SerialPort .NET 类。

我编写了相当大的 C# 应用程序来与调制解调器通信,拨号到其他调制解调器并通过它们进行通信。一切正常,直到我设法在两个调制解调器之间建立连接。发生这种情况时,两个调制解调器(应该是)从 COMMAND 模式(我可以将 Hayes 的命令发送到调制解调器)切换到 DATA 模式(我发送到调制解调器的所有数据都被转发到另一个调制解调器)。

我的应用程序可以向串口发送东西,也可以从串口接收东西。它安装在两台连接的 PC 上。但是当我在我的应用程序中输入一些东西时,例如“喂”,对方没有收到。奇怪的部分来了。下面是我如何通过串行端口发送消息(“端口”是 SerialPort 类的一个实例,“数据”是一个字符串的实例):

port.Write(data);

这样就可以了。它必须工作。特别是,因为如果我使用我的应用程序在一侧发送而 PuTTy 在另一侧接收 - 它有效!连接到有效串行端口的 PuTTy 收到我的消息。这也意味着,不仅我的消息到达了第一个调制解调器;它正在通过网络发送到另一个调制解调器,然后另一个调制解调器通过串行端口将它发送到接收PC。但这还不是全部。当我使用我的应用程序接收时,我使用 SerialPort.DataReceived 事件,就像这样(当然方法已经被 +=ed 到事件处理程序):

void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
//this message box should pop up if event hit:
MessageBox.Show("Data from serial port received!");
//calling my method to handle incoming message
DataReceived((SerialPort)sender);
}

当调制解调器(连接到接收 PC 的调制解调器)处于命令模式时,它可以工作。例如。当我向调制解调器发送“AT”Hayes 的命令时(仅表示“ping”),调制解调器响应“OK”,我收到了它。 SerialPort.DataReceived 事件触发。但是当这个调制解调器处于数据模式时(当我不能向它发送 Hayes 的命令时),它从发送调制解调器接收到一条消息,并将它转发到串行端口 - 没有。事件甚至没有触发。我检查的很好。

这很奇怪!

这只能让我得出结论,调制解调器向串行端口发送消息的方式在数据模式和命令模式下略有不同,PuTTy 以某种方式理解其他方式,而 SerialPort 类不.

我真的不明白。

最佳答案

你说当调制解调器处于命令模式时 DataReceived 事件不会触发,作为在串口/调制解调器通信方面有个人经验的人,我敢说当你从串口收集数据时你正在做一些阻塞操作。

到目前为止,我已经完成了几个使用 SerialPort 类的项目来处理使用 .NET40 的调制解调器通信,并且通信按预期进行。

我最好的猜测是您的方法 DataReceived((SerialPort)sender); 正在阻止进一步接收数据。

我为了在从锁中的端口收集接收到的数据时避免死锁,但在锁外处理它们并确保处理完成某些事情(不要做任何冗长的事情,否则它会挂起接收), 比如:

void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
var com = sender as SerialPort;
var lst = new List<byte>();

if (com != null)
{
lock (com)
{
do
{
if (com.BytesToRead == 0) break;
var one = com.ReadByte();
if (one >= 0 && one < 256) lst.Add(Convert.ToByte(one));
} while (one >= 0 && one < 256);

// lst.ToArray(); // get bytes
}

// ... // do something with received data
}
}

您没有提供有关数据处理的详细信息,所以我只能猜测该代码中有某种 block 。

在提供的样本中有两个要点:

  1. 独占读取数据,但只有当有数据可读时,不等待数据
  2. 尽快处理锁外接收到的数据并完成函数执行

此外,提供的代码(以类似的形式)总是在多线程应用程序中使用,因此 Main 上的 [MTAThread] 属性!

排除串行通信故障的最快方法之一可能是安装com0com,虚拟串口来自 http://com0com.sourceforge.net/并尝试不使用调制解调器直接通信,只是为了确保数据交换有效。

其实你可以在你的应用程序中使用它。只需安装一对虚拟 com 端口,将您的应用程序附加到一个串行端口,将 putty 附加到其他串行端口,当您在 putty 上看到 ATZ 时,只需响应 OK\r\n :)但是,如果您使用的是引脚读数,那么 putty 就帮不了您了,至少我不知道如何从 putty 更改标志。

我知道这个帖子有点旧,但欢迎提供一些反馈。

快乐编码。

关于c# - 为什么 System.IO.Ports.SerialPort.DataReceived 事件在调制解调器处于数据模式时不触发?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12857410/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com