Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么System.IO.Ports.SerialPort.DataReceived事件不';调制解调器处于数据模式时是否触发?_C#_.net_Serial Port_Modem - Fatal编程技术网

C# 为什么System.IO.Ports.SerialPort.DataReceived事件不';调制解调器处于数据模式时是否触发?

C# 为什么System.IO.Ports.SerialPort.DataReceived事件不';调制解调器处于数据模式时是否触发?,c#,.net,serial-port,modem,C#,.net,Serial Port,Modem,目前在我的大学里,我们正在做这些旧的56k调制解调器之间的通信。当从PC到调制解调器的消息通过串行端口传输时,我想使用System.IO.Ports.SerialPort.NET类 我编写了相当大的C#应用程序来与调制解调器通信,拨到其他调制解调器并通过它们进行通信。在我设法在两个调制解调器之间建立连接之前,一切都很顺利。当这种情况发生时,两个调制解调器(应该是)从命令模式(我可以将Hayes的命令发送到调制解调器)切换到数据模式(我发送到调制解调器的所有数据都被转发到另一个调制解调器) 我的应

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

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

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

所以它起作用了。它必须起作用。特别是,如果我使用我的应用程序在一边发送,在另一边使用PuTTy接收,它会工作!连接到有效串行端口的PuTTy接收我的消息。它还暗示,不仅我的信息到达第一个调制解调器;它通过网络发送到另一个调制解调器,然后另一个调制解调器通过串行端口发送到接收PC。但这还不是全部。当我使用我的应用程序接收时,我使用SerialPort.DataReceived事件,如下所示(当然方法已被+=ed到事件处理程序):

当调制解调器(连接到接收PC的调制解调器)处于命令模式时,它工作。例如,当我向调制解调器发送“AT”Hayes命令(这只意味着“ping”)时,调制解调器响应“OK”,我收到它。SerialPort.DataReceived事件激发。但当这个调制解调器处于数据模式时(当我无法向它发送Hayes的命令时),它从发送调制解调器接收到一条消息,并将其转发到串行端口-无。事件甚至不会触发。我检查得很好

真奇怪

这只会让我得出结论,调制解调器向串行端口发送消息的方式在数据模式和命令模式下略有不同,PuTTy不知何故理解了另一种方式,而SerialPort类则不理解


我真的不明白这一点。

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

到目前为止,我已经使用SerialPort类完成了几个项目,以使用.NET40处理调制解调器通信,并且通信工作正常

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

为了避免在收集接收到的数据时死锁,请从锁中的端口读取数据,但在锁外对其进行处理,并确保处理完成(不要执行任何冗长的操作,否则将挂起接收),例如:

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
    }
}
void端口\u数据接收(对象发送方,SerialDataReceivedEventArgs e)
{
var com=作为串行端口的发送方;
var lst=新列表();
如果(com!=null)
{
锁(com)
{
做
{
如果(com.BytesToRead==0)中断;
var one=com.ReadByte();
如果(一个>=0和一个<256)lst.Add(Convert.ToByte(一个));
}而(一个>=0和一个<256);
//lst.ToArray();//获取字节
}
//…//处理接收到的数据
}
}
您没有提供有关数据处理的详细信息,因此我只能猜测代码中有某种块

在提供的示例中,有两个要点:

  • 以独占方式读取数据,但仅当有数据要读取时,不要等待数据
  • 尽快处理锁外接收到的数据,并完成函数执行
  • 另外,提供的代码(类似的形式)总是在多线程应用程序中使用,所以Main上的[MTAThread]属性

    解决串行通信故障的最快方法之一可能是安装 com0com,来自的虚拟串行端口 并尝试在没有调制解调器的情况下直接通信,以确保数据交换工作正常

    实际上,您可以在应用程序中使用它。 只需安装一对虚拟com端口,将应用程序连接到一个串行端口,将putty连接到另一个端口,当您在putty上看到ATZ时,只需使用“确定”\r\n:) 但若你们使用的是引脚读数,那个么腻子对你们并没有帮助,至少我不知道用腻子来改变标志的方法

    我知道这条线有点旧,但欢迎提供一些反馈


    快乐的编码

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

    到目前为止,我已经使用SerialPort类完成了几个项目,以使用.NET40处理调制解调器通信,并且通信工作正常

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

    为了避免在收集接收到的数据时死锁,请从锁中的端口读取数据,但在锁外对其进行处理,并确保处理完成(不要执行任何冗长的操作,否则将挂起接收),例如:

    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
        }
    }
    
    void端口\u数据接收(对象发送方,SerialDataReceivedEventArgs e)
    {
    var com=作为串行端口的发送方;
    var lst=新列表();
    如果(com!=null)
    {
    锁(com)
    {
    做
    {
    如果(com.BytesToRead==0)中断;
    var o
    
    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
        }
    }