DevX Home    Today's Headlines   Articles Archive   Tip Bank   Forums   

Results 1 to 12 of 12

Thread: CopyMemory, Winsock and UDT

  1. #1
    Join Date
    Jan 2007
    Location
    Slovenia
    Posts
    5

    Angry CopyMemory, Winsock and UDT

    Hy, my first post on this forum
    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:
    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
    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

  2. #2
    Join Date
    Oct 2005
    Location
    Maady
    Posts
    1,819
    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 .
    Programmer&Cracker CS
    MyBlog:Blog.Amahdy.com
    MyWebsite:www.Amahdy.com

  3. #3
    Join Date
    Jan 2007
    Location
    Slovenia
    Posts
    5
    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

  4. #4
    Join Date
    Oct 2005
    Location
    Maady
    Posts
    1,819
    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 .
    Programmer&Cracker CS
    MyBlog:Blog.Amahdy.com
    MyWebsite:www.Amahdy.com

  5. #5
    Join Date
    Jan 2007
    Location
    Slovenia
    Posts
    5
    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....
    Last edited by BlackCatSLO; 01-20-2007 at 11:53 AM.


  6. #6
    Join Date
    Jan 2007
    Location
    Slovenia
    Posts
    5
    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


  7. #7
    Join Date
    Aug 2004
    Location
    Orange, California
    Posts
    1,263
    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.

  8. #8
    Join Date
    Jan 2007
    Location
    Slovenia
    Posts
    5
    Yes but i have to add header info becouse i have 20 UDTs


  9. #9
    Join Date
    Aug 2004
    Location
    Orange, California
    Posts
    1,263
    I did some experimenting and this is my test code. See what you think:
    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
        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
    Last edited by Ron Weller; 01-21-2007 at 07:20 AM.

  10. #10
    Join Date
    Aug 2004
    Location
    Orange, California
    Posts
    1,263
    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!!

  11. #11
    Join Date
    Oct 2005
    Location
    Maady
    Posts
    1,819

    Arrow

    Quote Originally Posted by BlackCatSLO
    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 .
    Programmer&Cracker CS
    MyBlog:Blog.Amahdy.com
    MyWebsite:www.Amahdy.com

  12. #12
    Join Date
    Oct 2005
    Location
    Maady
    Posts
    1,819
    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 .
    Programmer&Cracker CS
    MyBlog:Blog.Amahdy.com
    MyWebsite:www.Amahdy.com

Similar Threads

  1. WinSock
    By Nikolay in forum VB Classic
    Replies: 26
    Last Post: 10-27-2000, 08:01 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center
 
 
FAQ
Latest Articles
Java
.NET
XML
Database
Enterprise
Questions? Contact us.
C++
Web Development
Wireless
Latest Tips
Open Source


   Development Centers

   -- Android Development Center
   -- Cloud Development Project Center
   -- HTML5 Development Center
   -- Windows Mobile Development Center