Open lionpeloux opened 5 years ago
Ciao Lionel,
sorry for the delay. Currently I do not have time to check, but I have shared the sources on github
Massimiliano
Il giorno ven 25 gen 2019 alle ore 12:37 Lionel du Peloux < notifications@github.com> ha scritto:
Hello,
I'm working on a C# client for KukavarProxy. So far I came up with a yet almost working solution using the sparse info I've found on the net about this tool (specially here https://github.com/akselov/kukavarproxy-msg-format).
My first question is would you be able to share in few lines the structure of the TCP packets that we should adopt to discuss with KukavarProxy ? For readquery, writequery and answer ? So far, I came up with this : readquery
- 2 bytes ID (uint16)
- 2 bytes content length (uint16)
- 1 byte for read (0) or write (1) mode
- 2 bytes for the variable name length (uint16)
- N bytes for the variable name to be read (ASCII -> bytes)
writequery
- 2 bytes ID (uint16)
- 2 bytes content length (uint16)
- 1 byte for read (0) or write (1) mode
- 2 bytes for the variable name length (uint16)
- N bytes for the variable name to be read (ASCII -> bytes)
- 2 bytes for the variable value length (uint16)
- M bytes for the variable value to be written (ASCII -> bytes)
answer
- 2 bytes ID (uint16)
- 2 bytes content length (uint16)
- 1 byte for read (0) or write (1) mode
- 2 bytes for the variable value length (uint16)
- M bytes for the variable value to be written (ASCII -> bytes)
- 3 bytes tail [0, 1, 1]
=> Can you confirm I've correctly understood all this ? => Can you tell us more about the tail ? Is it always 011 ? Does it have any meaning or is it just a separator ?
=> When I send very fast requests to the server, In the debug window I see some messages are "Split". When I read the answers back, wherever a message were marked "Split" the Id is not incremented correctly. How can I prevent this to happen other than slowing down my queries ?
This what I send to the proxy :
Query 1 : 01 03 0 00 Query 2: 02 03 0 00 Query 3 : 03 03 0 00 Query 4 : 04 03 0 00 Query 5 : 05 03 0 00 => Message Split Query 6 : 06 03 0 00 => Message Split Query 7 : 07 03 0 00 Query 8 : 08 03 0 00 => Message Split Query 9 : 09 03 0 00 => Message Split Query 10 : 10 03 0 00
When I read back the stream I get :
Msg[1] with Id = 1 : 01 06 0 00 110 Msg[2] with Id = 2 : 02 06 0 00 110 Msg[3] with Id = 3 : 03 06 0 00 110 Msg[4] with Id = 4 : 04 06 0 00 110 Msg[5] with Id = 4 : 04 06 0 00 110 Msg[6] with Id = 4 : 04 06 0 00 110 Msg[7] with Id = 7 : 07 06 0 00 110 Msg[8] with Id = 7 : 07 06 0 00 110 Msg[9] with Id = 7 : 07 06 0 00 110 Msg[10] with Id = 10 : 10 06 0 00 110
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/ImtsSrl/KUKAVARPROXY/issues/3, or mute the thread https://github.com/notifications/unsubscribe-auth/AKYlDSFRo4aHe8MQkDGN3Z2hOWpm1llMks5vGuxmgaJpZM4aStxf .
-- Massimiliano Fago Senior Software Engineer massimiliano.fago@gmail.com skype: massimomfa
Ok, so looking carefully at the code I think I effectively found a bug !
Split
message is when the buffer is filled with several messages so the byte stream is "splitted" between each messages. Nothing wrong with that.
However, while the variable nMsg
is correctly incremented, the string to write is built each time with sMsgID
which is set at the beginning of the loop but is never updated when splits occurred.
I'll try to make a pull request for that next week.
Private Sub sockServer_Read(Index As Integer, DataLength As Integer, IsUrgent As Integer)
Dim strBuffer As String
Dim cchBuffer As Integer
Static bReadPending As Boolean
On Error GoTo errRead
' read the first 2048 bytes in the socket buffer
' put the received bytes (n <= 2048) in strBuffer
cchBuffer = sockServer(Index).Read(strBuffer, 2048)
If (cchBuffer < 0) Then
'If a would block error occurs exit the sub and let
'another read event read when the client is ready
If (sockServer(Index).LastError = WSAEWOULDBLOCK) Then
Exit Sub
End If
'If an in progress error occurs exit the sub and let
'another read event read when the client is ready
If (sockServer(Index).LastError = WSAEINPROGRESS) Then
Exit Sub
End If
'There has been an error in the read
'print the error and quit
DropClient Index, "Error occurred durring the read event: Error #", sockServer(Index).LastError
UpdateForm
Exit Sub
End If
Dim sValueToWrite As String
Dim lLunghezzaBlocco As Long ' Length of the bloc
Dim lLunghezzaBloccoToWrite As Long ' Length of the bloc to write
Dim sAzione As String ' Action
Dim lMsgID As Long ' Msg Id
Dim sMsgID As String
Dim nFunction As Integer
' the first 2 bytes indicate the ID of the received message
lMsgID = CLng(Asc(Mid(strBuffer, 1, 1))) * &H100 + Asc(Mid(strBuffer, 2, 1))
sMsgID = Mid(strBuffer, 1, 2)
' the next 2 bytes indicate the length of the bloc
lLunghezzaBlocco = Asc(Mid(strBuffer, 3, 1)) * &H100 + Asc(Mid(strBuffer, 4, 1))
' then walk byte by byte until the end of the bloc
nMsg = 0
While Len(strBuffer) >= lLunghezzaBlocco
'DoEvents
nMsg = nMsg + 1
' extract the message content as a string (froom byte 6 to byte lLunghezzaBlocco)
strMsg = Mid(strBuffer, 6, lLunghezzaBlocco)
' extract the query function (0=READ, 1=WRITE)
nFunction = CInt(Asc(Mid(strBuffer, 5, 1)))
If Not bReadPending Then
' is this a lock to prevent concurrent reading operations ?
' shouldn't we wait here until bReadPending = false ?
' gets the lock ?
bReadPending = True
' read the msg
If readMsg(nFunction, strMsg, sValueToWrite, sAzione) Then
lLunghezzaBloccoToWrite = Len(sValueToWrite)
sValueToWrite = sMsgID & longToWord(lLunghezzaBloccoToWrite) & sValueToWrite
If frmMain.sockServer(Index).Write(sValueToWrite, Len(sValueToWrite)) < 0 Then
DropClient Index, "Error occurred durring the read event: Error #", sockServer(Index).LastError
End If
If frmMain.chkDebug.Value = 1 Then
addMessage "ID=" & lMsgID & " " & sAzione
End If
End If
bReadPending = False
Else
addMessage "!!Lettura pendente!!"
End If
' remove the message from strBuffer (msg = ID + Len + bloc) / even if we skip the read because bReadPending was true ?
strBuffer = Right(strBuffer, Len(strBuffer) - (lLunghezzaBlocco + 4))
' if they are enough bytes in the buffer => should be > 3 no ?
If Len(strBuffer) > 2 Then
' the first 2 bytes indicate the ID of the received message
lMsgID = CLng(Asc(Mid(strBuffer, 1, 1))) * &H100 + Asc(Mid(strBuffer, 2, 1))
' the next 2 bytes indicate the length of the bloc
lLunghezzaBlocco = Asc(Mid(strBuffer, 3, 1)) * &H100 + Asc(Mid(strBuffer, 4, 1))
' display debug msg
If frmMain.chkDebug.Value = 1 Then
addMessage "Split msg: " & nMsg & " ID=" & lMsgID & " " & sAzione
End If
Debug.Print "Msg separato numero " & nMsg & ": " & strMsg
End If
Wend
'Debug.Print "Lunghezza attesa: " & lLunghezzaBlocco & " lunghezza ricevuta: " & Len(strBuffer)
'memorizzo il tempo di arrivo del messaggio
lLastReciveTime(Index) = GetTickCount()
On Error GoTo 0
Exit Sub
errRead:
On Error GoTo 0
addMessage "Errore in Read"
addMessage "Msg ID " & lMsgID
addMessage "Msg Len " & lLunghezzaBlocco
addMessage "Buffer Len " & Len(strBuffer)
addMessage strMsg
bReadPending = False
End Sub
Hello,
I'm working on a C# client for KukavarProxy. So far I came up with a yet almost working solution using the sparse info I've found on the net about this tool (specially here).
My first question is would you be able to share in few lines the structure of the TCP packets that we should adopt to discuss with KukavarProxy ? For
readquery
,writequery
andanswer
? So far, I came up with this :readquery
writequery
answer
=> Can you confirm I've correctly understood all this ? => Can you tell us more about the tail ? Is it always 011 ? Does it have any meaning or is it just a separator ?
=> When I send very fast requests to the server, In the debug window I see some messages are "Split". When I read the answers back, wherever a message were marked "Split" the Id is not incremented correctly. How can I prevent this to happen other than slowing down my queries ?
This what I send to the proxy :
When I read back the stream I get :