Categories: MSDN / DotNet / Java / Scripts / Linux / PHP Ask - La ask - La Answer

CopyMemory, Winsock and UDT

Hy, my first post on this forum :D
Now the problem... when i copy UDT with copymemory to string and that send string with winsock(TCP) i come to the problem i copy string in to the UDT on the another peer i get wrong data.
Im using Winsock Component not API.
this is UDT
public Type SERVERINFO_TYPE
clientID as integer
clientType as byte
connAlowed as boolean
serverIP as string * 20

End Type

instead of this
-32766
255
True
127.0.0.1
i get this:
63
2
False
127.0.01

Please help me becouse this problem is freaking me out for 7days and i can not get what is wrong
VB6 server code:

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal dest As Long, _
ByVal source As Long, _
ByVal bytes As Long)

Private Type SERVERINFO_TYPE
ConnAllowed As Boolean
serverIP As String * 20
clientID As Integer
clientType As Byte
End Type

Private Sub Command1_Click()
Dim htt As String
Dim tss As String
Dim sif As SERVERINFO_TYPE
Dim sfi As SERVERINFO_TYPE

With sif
.clientID = -32766
.clientType = 255
.ConnAllowed = True
.serverIP = "127.0.0.1"
End With

htt = Space(Len(sif))
Call CopyMemory(StrPtr(htt), VarPtr(sif), LenB(sif) )

tss = htt

Picture1.Print ">" & tss & "<"

socket(Text2.Text).SendData tss

List1.AddItem "data len:" & LenB(htt)
Call CopyMemory(VarPtr(sfi), StrPtr(htt), Len(sfi))

With sfi
List1.AddItem .clientID
List1.AddItem .clientType
List1.AddItem .ConnAllowed
List1.AddItem .serverIP
End With

htt = ""
End Sub

Private Sub Form_Load()

socket(0).Listen

End Sub

Private Sub Form_QueryUnload(Cancel As Integer, UnloadMode As Integer)
Cancel = False
socket(0).Close

End Sub

Private Sub socket_Close(Index As Integer)
socket(Index).Close
Unload socket(Index)

End Sub

Private Sub socket_ConnectionRequest(Index As Integer, ByVal requestID As Long)
If Index = 0 Then
Load socket(requestID)
socket(requestID).LocalPort = 8500

If True Then
socket(requestID).Accept requestID
List1.AddItem "ID:" & requestID
Text2.Text = requestID
Else
socket_Close (requestID)
End If

End If
End Sub




client Code

Option Explicit
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal dest As Long, _
ByVal source As Long, _
ByVal bytes As Long)

Private Type SERVERINFO_TYPE
ConnAllowed As Boolean
serverIP As String * 20
clientID As Integer
clientType As Byte
End Type

Private obj As Object
Private hmm As Boolean

Dim strBuffer As String

Private Sub Command1_Click()

Dim sfi As SERVERINFO_TYPE
Dim sif2 As SERVERINFO_TYPE
Dim strData As String
Dim strBuffer As String
Dim i As Integer

Dim datalen As Integer
Dim data As String
Dim datatype As Integer
Dim nop As Integer

socket.Connect "127.0.0.1", 8500

hmm = False

Do While hmm = False
DoEvents
If socket.State = 7 Then
socket.PeekData strData, vbString

If LenB(strData) > 0 Then '' if peakdata gets string then...
List1.AddItem "data rec:" & socket.BytesReceived
socket.GetData strData, vbString

strBuffer = strData
List1.AddItem "data len:" & LenB(strData)




strData = ""

Call CopyMemory(VarPtr(sfi), StrPtr(strBuffer), LenB(sfi))


Cls
Picture1.Print ">" & strBuffer & "<"

With sfi
List1.AddItem "clientID:" & .clientID
List1.AddItem "clientType:" & .clientType
List1.AddItem "ConnAllowed:" & .ConnAllowed
List1.AddItem "serverIP:" & .serverIP & "<<"
End With



End If
ElseIf socket.State = sckError Then


End If

Loop

End Sub
[4873 byte] By [BlackCatSLO] at [2007-11-11 10:13:25]
# 1 Re: CopyMemory, Winsock and UDT
from MSDN:

If the type is specified as vbString, string data is converted to UNICODE before returning to the user.

If u use the peekdata to know if u have recived data or not yet;
u may use the socket_DataArrival() I think it's better .
Amahdy at 2007-11-11 17:23:00 >
# 2 Re: CopyMemory, Winsock and UDT
If u use the peekdata to know if u have recived data or not yet;
u may use the socket_DataArrival() I think it's better .


yes i know the dataarrival is better but this is just test client and server becouse the server on the real thing had sent data to client(game) but client didnt recived so i did write this to see what can solve sending and reciving problem but when i was testing this i was find out one more problem with copymemory and here im with this problem...

If the type is specified as vbString, string data is converted to UNICODE before returning to the user.

Soo what do i have to do?
tnx
BlackCatSLO at 2007-11-11 17:24:03 >
# 3 Re: CopyMemory, Winsock and UDT
I really don't love peekdata at all, why not try to solve your original problem instead ?
well I think to solve this u may need to convert the string back from unicode to ascii .
Amahdy at 2007-11-11 17:25:01 >
# 4 Re: CopyMemory, Winsock and UDT
if i understand, i have to use strconv?

EDIT: i used this function StrConv on both sides(server & client) and i did send string over winsock and recived all data as spoposed to do so this thing is working...
BlackCatSLO at 2007-11-11 17:26:06 >
# 5 Re: CopyMemory, Winsock and UDT
Now i have another problem...
this problem is not on the test app but is on real app...
When i connect with client to the server client sends self data and then server sends back server info and then client sends "cmd" string to server so the server can send back clientinfo but problem is...
Server sends data but client doesnt recive it and this problem is making me norveus
on client runs renderloop which is drawing on screen...and its have doevents
i dont know what can be a problem.
dataarrival event doesnt trigger and in winsock buffer is nothing.(on client side)
when i disconnect client server sings err 10053
tnx for help
BlackCatSLO at 2007-11-11 17:27:01 >
# 6 Re: CopyMemory, Winsock and UDT
Also if you use a Byte Array instead of a vbString then the unicode conversion will not be performed and you should get the data exactly as you send it.
Ron Weller at 2007-11-11 17:28:00 >
# 7 Re: CopyMemory, Winsock and UDT
Yes but i have to add header info becouse i have 20 UDTs
BlackCatSLO at 2007-11-11 17:29:04 >
# 8 Re: CopyMemory, Winsock and UDT
I did some experimenting and this is my test code. See what you think:Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByVal dest As Long, ByVal Source As Long, ByVal bytes As Long)

Private Type SERVERINFO_TYPE
serverIP As String * 20
ConnAllowed As Boolean
clientID As Integer
clientType As Byte
End Type

Public Sub StrToBytes()
Dim I As Long
Dim strBuf As String
Dim outBuf() As Byte
Dim sif As SERVERINFO_TYPE
Dim sfi As SERVERINFO_TYPE


With sif
.clientID = -32766
.clientType = 255
.ConnAllowed = True
.serverIP = "127.0.0.1"
End With

Debug.Print "data len:" & LenB(sif)
With sif
Debug.Print .clientID
Debug.Print .clientType
Debug.Print .ConnAllowed
Debug.Print .serverIP
End With

'pack header and spaces enough for sfi UDT into outBuf
outBuf = StrConv("Header" & Space(LenB(sif)), vbFromUnicode)
'copy sif into outBuf starting after the header info in bytes 0 to 5
Call CopyMemory(VarPtr(outBuf(6)), VarPtr(sif), LenB(sif))


'socket(Text2.Text).SendData outBuf
For I = LBound(outBuf) To UBound(outBuf)
Debug.Print outBuf(I);
Next I
Debug.Print



Debug.Print "data len:" & UBound(outBuf) + LBound(outBuf)
'copy outBuf starting after the header info in bytes 0 to 5 into sfi
Call CopyMemory(VarPtr(sfi), VarPtr(outBuf(6)), LenB(sfi))
With sfi
Debug.Print .clientID
Debug.Print .clientType
Debug.Print .ConnAllowed
Debug.Print .serverIP
End With


Erase outBuf

End Sub
Ron Weller at 2007-11-11 17:30:07 >
# 9 Re: CopyMemory, Winsock and UDT
I noticed that when you load a UDT that has a string in it into a string; that data can get lost because of the Unicode conversions The string in the UDT is also a unicode string but the other data is not, so when converted to a string it gets a little messy. The bytes of the data that is not a unicode string get treated as if they were. Every other byte gets hacked off when converting back and fourth. So here I packed the UDT directly into the part of my byte array where I wanted it. No conversion needed here. I do use the convert for allocating the space in my byte array so that I don't allocate twice as much room as needed and since the added header info is also string info, it gets converted to non unicode data when packed into the byte array. But the string embeded in the UDT remains intact.
Now if you load the UDT into a string and then convert it to a unicode string, and then add the header text. You would then need to convert it back to non unicode before sending it, otherwise you would be sending twice the number of bytes then you actually needed. But once you received the data on the other side you would have to convert it to a unicode string, seperate the UDT data from the header info and then convert the UDT data back to non unicode so that you could then extract the UDT data back into a UDT structure. Anyway, you can play around with the test routine and by dumping the byte array to the Immediate window you can actually see what is getting loaded into your buffer and how Unicode conversions effect the outcome. Have fun!!
Ron Weller at 2007-11-11 17:31:06 >
# 10 Re: CopyMemory, Winsock and UDT
Now i have another problem...
this problem is not on the test app but is on real app...
When i connect with client to the server client sends self data and then server sends back server info and then client sends "cmd" string to server so the server can send back clientinfo but problem is...
Server sends data but client doesnt recive it and this problem is making me norveus
on client runs renderloop which is drawing on screen...and its have doevents
i dont know what can be a problem.
dataarrival event doesnt trigger and in winsock buffer is nothing.(on client side)
when i disconnect client server sings err 10053
tnx for help

The problem should be in the way of sending itself or the way u think the client will recive data with it ..
just tell me what u do exactly to send and to resive , and if u have tried to debug the recive process maybe u recive data and the problem is using this data as u said u want a cmd command ; maybe the problem in the using of this cmd ..
just send me here a snap of the code , or explication of yor events .
Amahdy at 2007-11-11 17:32:07 >
# 11 Re: CopyMemory, Winsock and UDT
Ron made me remember at your original post when using vbString , u just need to know if the peekdata return a value bigeer than zero or nop, so u may change the vbString to anything else whatever is it, it will return a value , and to be safe either check if the return <> 0 or use vbByte , that's because other conversations may return a negative value and it's a data .
Amahdy at 2007-11-11 17:33:05 >