C# 串行端口类的问题
我有一个串行端口类,看起来像这样:C# 串行端口类的问题,c#,serial-port,C#,Serial Port,我有一个串行端口类,看起来像这样: public static class OldHaspCommunication { private static SerialPort m_port; private static string m_portName; private static bool m_isOpen = false; private static int m_baudRate; private static Parity m_parit
public static class OldHaspCommunication
{
private static SerialPort m_port;
private static string m_portName;
private static bool m_isOpen = false;
private static int m_baudRate;
private static Parity m_parity;
private static int m_dataBits;
private static StopBits m_stopBits;
private static bool m_xonxoff;
private static bool m_dtr;
private static bool m_rts;
// ................................
// Open port.
public static void OpenPort(string portName,
int baudRate,
Parity parity,
int dataBits,
StopBits stopBits,
bool dtr,
bool rts,
bool xonxoff = false)
{
// Create new Serial Port object
m_port = new SerialPort(portName, baudRate, parity, dataBits, stopBits);
// .........................................
// Set class member variables.
m_portName = portName;
m_baudRate = baudRate;
m_parity = parity;
m_dataBits = dataBits;
m_stopBits = stopBits;
m_xonxoff = xonxoff;
m_dtr = dtr;
m_rts = rts;
// ............................................
// Initialize some port object properties
// XOnXOff - parameter
if (xonxoff)
m_port.Handshake = Handshake.XOnXOff;
// Set DTR/RTS
m_port.DtrEnable = dtr;
m_port.RtsEnable = rts;
// Set
m_port.ReadTimeout = 500;
m_port.WriteTimeout = 500;
// ..............................................
// Some final steps.
// Open the port for communications
m_port.Open();
// If we get this far, mark port as opened.
m_isOpen = true;
}
/// <summary>
/// Just makes sure to read the specified number of bytes from the serial port.
/// Typical reads may return fewer bytes then told to read. This method is used
/// to avoid this problem.
/// Based on a similar function from Jon Skeet: http://jonskeet.uk/csharp/readbinary.html
/// </summary>
/// <param name="data"> [OUT] Data read should be stored here</param>
/// <param name="length"> [IN] How much data to read exactly </param>
/// <param name="count"> [IN] Some kind of retry count parameter.</param>
private static void ReadAll(byte[] data, uint length, int retryCount)
{
// Check data length parameter.
if (length > data.Length)
{
throw new Exception("Wrong data length in ReadAll");
}
int offset = 0;
int i = 0;
int remaining = checked((int)length); // NOTE: Will throw OverflowException if length > Int32.MaxValue due to checked keyword.
// Start reading.
while (remaining > 0)
{
// Just a retry count check
if (i >= retryCount)
{
throw new Exception("Exceeded retry count parameter during reading in ReadAll");
}
// Read Certain amount of bytes
int read = m_port.Read(data, offset, remaining);
// Was there error?
if (read <= 0)
{
throw new EndOfStreamException(String.Format("ReadAll(OldHaspCommunication) - End of data reached with {0} bytes left to read", remaining));
}
// Advance offset, and decrease remaining count.
remaining -= read;
offset += read;
i++;
}
}
/// <summary>
/// Write specified number of bytes to the serial port
/// </summary>
/// <param name="data"> [IN] Buffer from which to write data</param>
/// <param name="length"> [IN] How many bytes to write</param>
private static void WriteAll(byte[] data, uint length)
{
// TODO: Maybe we should add a retry count as in C++
int len = checked((int)length); // NOTE: Will throw OverflowException if length > Int32.MaxValue due to checked keyword.
// We can't write more data to serial port than available in the array.
if (len > data.Length)
{
throw new Exception("Wrong data length in WriteAll");
}
// Do the write.
m_port.Write(data, 0, len);
}
/// <summary>
/// Close the serial port.
/// NOTE: Don't forget to call this one.
/// </summary>
public static void ClosePort()
{
if (m_isOpen)
{
Reset(); // Calls our custom Reset function.
m_port.Close(); // Close port
m_isOpen = false; // Mark this object as closed.
}
}
// ...
private static void Reset()
{
m_port.DiscardInBuffer();
m_port.DiscardOutBuffer();
}
}
Query
函数(上面列出的)也来自HASP类-为了清晰起见,我删除了它们,它们只是以不同的方式调用read/write
方法,在某些情况下可能调用Reset
你能解释一下发生了什么问题以及原因吗?(Reset
函数被一个Query
函数调用)。
这一定与我拔下搭扣有关吧?
但为什么会有这样的例外
如何修改我的类,以便如果有人拔下搭扣然后将其插入,对搭扣的调用仍然成功?
请注意,最初我的设计是在应用程序中调用一次
OpenPort
。在应用程序中调用ClosePort
。虽然捕获异常代价很高,但我认为您需要捕获它,如果我没有弄错的话,您使用的HASP是USB到COM emulator
- 您可以使用WMI检测HASP(USB)连接——或
- 在ReadAll/WriteAll/Reset上断开连接期间捕获异常--或
- 创建线程以监视异常,并重新启动线程以重试连接
将在一段时间内尝试提供伪代码。请先尝试理解问题。事实上,我检查了,当我拔下HASP时,SerialPort类的isOpen属性仍然返回true,只是协议报告的签名计算失败。我必须与HASPif对话,如果我不删除HASP,它工作正常;这只是我连接到COM端口的正常搭扣
2016-02-10 13:01:14 - [LOG_ERROR] [THREAD ID: 11] General Exception: Object reference not set to an instance of an object.
System.NullReferenceException: Object reference not set to an instance of an object.
at ProcessingLibrary.OldHaspCommunication.Reset() in c:\Users\g.\Documents\Visual Studio 2012\Projects\ProcessingLibrary\ProcessingLibrary\src\HASP\OldHaspCommunication.cs:line 270
at ProcessingLibrary.OldHaspCommunication.QueryParam(Byte[] in_buffer, UInt32 length, Byte command, Byte[] out_buffer, UInt32 szBuf, Byte& ret_code, Int32 l_entry, Int32 l_loop, Boolean quick_ser_no) in c:\Users\g.\Documents\Visual Studio 2012\Projects\ProcessingLibrary\ProcessingLibrary\src\HASP\OldHaspCommunication.cs:line 303
at ProcessingLibrary.OldHaspCommunication.Query(Byte[] in_buffer, UInt32 length, Byte command, Byte[] out_buffer, UInt32 szBuff, Byte& retcode) in c:\Users\g.\Documents\Visual Studio 2012\Projects\ProcessingLibrary\ProcessingLibrary\src\HASP\OldHaspCommunication.cs:line 277
at ProcessingLibrary.OldHaspCommunication.QueryCmd8(Byte[] in_buffer, Byte command, Byte[] out_buffer) in c:\Users\g.\Documents\Visual Studio 2012\Projects\ProcessingLibrary\ProcessingLibrary\src\HASP\OldHaspCommunication.cs:line 286
at ProcessingLibrary.CryptographyUtilities.SetSessionKey() in c:\Users\g.\Documents\Visual Studio 2012\Projects\ProcessingLibrary\ProcessingLibrary\src\Security\CryptographyUtilities.cs:line 94
at ProcessingLibrary.CryptographyUtilities.OldHASPSign(Byte[] buffer, UInt32 size, Byte[] outbuffer, Boolean session) in c:\Users\g.\Documents\Visual Studio 2012\Projects\ProcessingLibrary\ProcessingLibrary\src\Security\CryptographyUtilities.cs:line 137
at ProcessingLibrary.UpdateTerminalInfoMethods.TestConnection(ProcessingErrorInfo& errorInfo, String terminalID, UInt32 STAN) in c:\Users\g.\Documents\Visual Studio 2012\Projects\ProcessingLibrary\ProcessingLibrary\src\Processing Functions\UpdateTerminalInfoMethods.cs:line 70