簡體   English   中英

為什么調制解調器處於DATA模式時不會觸發System.IO.Ports.SerialPort.DataReceived事件?

[英]Why System.IO.Ports.SerialPort.DataReceived event doesn't fire when modem is in DATA mode?

目前在我的大學,我們正在這些舊的56k調制解調器之間進行通信。 當從PC到調制解調器的消息通過串口時,我想使用System.IO.Ports.SerialPort .NET類。

我寫了很大的C#應用​​程序與調制解調器通信,撥打其他調制解調器並通過它們進行通信。 一切正常,直到我設法在兩個調制解調器之間建立連接。 當發生這種情況時,兩個調制解調器(應該是)從命令模式(我可以將Hayes的命令發送到調制解調器)切換到DATA模式(我發送到調制解調器的所有數據都被轉發到另一個調制解調器)。

我的應用程序可以發送內容,也可以從串口接收內容。 它安裝在兩台連接的PC上。 但是當我在我的應用程序中鍵入內容時,例如“Hello”,則不會在另一側收到。 這是奇怪的部分。 以下是我通過串口發送消息的方式('port'是SerialPort類的實例,'data'是字符串的實例):

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)處於COMMAND模式時,它可以工作。 例如,當我將“AT”Hayes的命令發送到調制解調器(這意味着只有'ping')時,調制解調器響應“OK”,然后我收到它。 觸發SerialPort.DataReceived事件。 但是當這個調制解調器處於DATA模式時(當我無法向它發送Hayes的命令時),它會從發送調制解調器收到一條消息,並將其轉發到串口 - 沒有。 事件甚至沒有發生。 我檢查得很好。

有點奇怪!

這只能讓我得出結論,調制解調器向串口發送消息的方式在DATA模式和COMMAND模式下略有不同,而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
    }
}

你沒有提供有關數據處理的細節,所以我只能猜測在那段代碼中是某種塊。

在提供的樣本中有兩個要點:

  1. 專門讀取數據但僅在有數據要讀取時,不要等待數據
  2. 處理鎖外的數據盡快並完成功能執行

此外,提供的代碼(類似的形式)總是在多線程應用程序中使用,因此Main上的[MTAThread]屬性!

對串行通信進行故障排除的最快方法之一可能是從http://com0com.sourceforge.net/安裝com0com,虛擬串口,並嘗試不使用調制解調器直接通信,只是為了確保數據交換有效。

實際上你可以在你的應用程序中使用它。 只需安裝一對虛擬COM端口,將您的應用程序連接到一個串行端口,將putty連接到其他端口,當您看到putty上的ATZ時只需用OK \\ r \\ n進行響應:)但是如果您使用的是引腳讀數則膩子不能幫助你,至少我不知道從膩子改變旗幟的方法。

我知道這個帖子有點舊,但歡迎一些反饋。

快樂的鱈魚。

由於Handshake未正確設置,因此未觸發SerialDataReceivedEventHandler

我不得不使用硬件流控制,這是Handshake.RequestToSend ,現在它正在為我工​​作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM