1
我正在編寫一個Java應用程序來替換VB6應用程序。應用程序必須使用10字節的二進制協議輪詢遠程系統,響應也是一個10字節的二進制消息,其中最後一個字節是通過總結所有前面的字節計算得出的校驗和。VB6應用程序vs Java 8u60串行通信
我遇到的問題是Java應用程序中校驗和不匹配的大量錯誤。
結果是相當可重複的。 VB6應用程序幾乎沒有錯誤,但Java應用程序有很多。我檢查了端口設置,它們是相同的19200,n,8,1。
在VB6端口建立串行端口已建立如下:
CDTimeout = 0
CommPort = 1
CTSTimeout = 0
DSRTimeout = 0
DTREnable = False
EOFEnable = False
Handshaking = None
InBufferCount = 0
InBufferSize = 1024
Index = 0
InputLen = 0
InputMode = comInputModeBinary
Interval = 1000
Name = "comInterfaceUnit"
NullDiscard = False
OutBufferSize = 512
ParityReplace = "?"
RThreshold = 10
RTSEnable = False
Settings = "19200,n,8,1"
SThreshold = 0
Tag = ""
的javax.comm的SerialPort建立如下:
baudrate = 19200
closed = false
databits = 8
dtr = false
flowcontrol = 0
framing = false
framingByte = 0
framingByteReceived = false
name = "COM1"
nativeHandle = 324295048
notifyMask = 1
parity = 0
rcvThreshold = -1
rcvTimeout = -1
rts = true
startBI = false
stateCD = false
stateCTS = false
stateDSR = false
stateFE = false
stateOE = false
statePE = false
stateRI = false
stopBits = 1
在VB6事件處理程序只是將接收字節複製到一個字節數組中,這正是Java代碼通過SerialEvent執行的操作。
Java的校驗和計算:
int intChecksumInPkt = (int)(arychrMsg[RESPONSE_LENGTH -1] & 0xff) ,intCalcChecksum = 0;
for(int b=0; b<RESPONSE_LENGTH -1; b++) {
intCalcChecksum += (int)(arychrMsg[b] & 0xff);
}
intCalcChecksum &= 0xff;
if (intCalcChecksum == intChecksumInPkt) { ... }
VB6校驗碼:
intSum = 0
For intI = gintInterfaceUnitReplyStatusOffset To gintInterfaceUnitReplyData8Offset
intSum = intSum + CInt(gbytInterfaceUnitReplyArray(gintCommPortIndex, intI))
Next intI
If gbytInterfaceUnitReplyArray(gintCommPortIndex, gintInterfaceUnitReplyChecksumOffset) = CByte(intSum And &HFF) Then
' Match, so a 'good' message.
blnFunctionValue = True
End If
我懷疑其他地方的錯誤。你可以添加校驗和計算方法嗎?並且接收部分也... – Fildor
校驗和非常簡單,從數據包的第一個字節開始,總結到數據包的最後一個字節,不包括數據包中最後一個字節的校驗和。 – SPlatten
簡單,但是當「翻譯」到java時,有很多錯誤空間。但我不想在沒有看到使用的實際代碼的情況下進行推測。通常有鑄造問題。在那裏,做到了 - 發瘋了,學到了一些東西。我首先會這樣做:檢查發送的相同數據是否會導致在VB6和Java解決方案中接收到相同的數據。然後(其次)在調試器中真正執行它,並檢查兩個和數何時開始不同。 – Fildor