Results 1 to 9 of 9

Thread: [RESOLVED]Sending Images With Winsock

  1. #1

    Thread Starter
    Lively Member outcast24817's Avatar
    Join Date
    Nov 2004
    Location
    USA
    Posts
    122

    Resolved [RESOLVED]Sending Images With Winsock

    I am making a multi-user drawing program, when a client connects to the server, the server sends him the current picture as a BMP (I don't need any compression, it's a small image, and it's only downloaded once.) After that, the client sends data to the server telling it where to place a new line. The server then repeats that data to all the other connections.

    So the only major problem I have is sending the data via Winsock. I can make multiple connections and such, but I cant send the picture. I've searched the forums here, and I've tried most of the suggestions, I have loaded the picture into a byte array with this code:

    VB Code:
    1. Private Function SendPic(Index As Integer)
    2. Dim Size As Long
    3. Dim Filenum As Integer
    4. Dim AByte() As Byte
    5. Dim i As Integer
    6.  
    7. 'save pic
    8. SavePicture picMain.Picture, "C:\SDraw.bmp"
    9.  
    10. Filenum = FreeFile
    11. Open "C:\SDraw.bmp" For Binary Access Read As Filenum
    12. ReDim AByte(FileLen("C:\SDraw.bmp") - 1)
    13. Get #Filenum, , AByte
    14. Close Filenum
    15.  
    16. Size = UBound(AByte)
    17. WS(Index).SendData "Image:" & Size & ":" & Str(AByte())
    18. WS(Index).SendData AByte
    19. End Function

    But I get all sorts of problems with that code, I don't think its even putting the entire file into the array to begin with. I don't even know how to go about receiving the data correctly. Can someone show me an easy way to transfer a file with Winsock, or a way to get this code working?

    Thanks.
    Last edited by outcast24817; Dec 22nd, 2006 at 05:24 PM.
    **not completely learned**
    Complete control of the registry ~

  2. #2
    PowerPoster
    Join Date
    Feb 2002
    Location
    Canada, Toronto
    Posts
    5,803

    Re: Sending Images With Winsock

    I know that the most efficient way is to use a Byte Array, but for simplicity (and since the picture is not large), do this:
    VB Code:
    1. Private Function SendPic(Index As Integer)
    2.     Dim Size As Long
    3.     Dim FileNum As Integer
    4.     Dim Buffer As String
    5.    
    6.     SavePicture picMain.Picture, "C:\SDraw.bmp"
    7.    
    8.     FileNum = FreeFile
    9.     Open "C:\SDraw.bmp" For Binary Access Read As FileNum
    10.     Buffer = String(LOF(FileNum), 0)
    11.     Get #FileNum, , Buffer
    12.     Close FileNum
    13.    
    14.     Size = Len(Buffer)
    15.     WS(Index).SendData "Image:" & Size & ":" & Buffer
    16. End Function
    If this does not work, then it means that you might also have problems when receiving the data.

  3. #3

    Thread Starter
    Lively Member outcast24817's Avatar
    Join Date
    Nov 2004
    Location
    USA
    Posts
    122

    Re: Sending Images With Winsock

    Thanks, CVMichael. I can now send the image, but only the first ~8 KB arrives, do I have to set up my code to handle data coming in chunks, or what?

    Here is the receiving code:
    VB Code:
    1. Private Sub WS_DataArrival(Index As Integer, ByVal bytesTotal As Long)
    2. Dim IncomingData As String
    3. Dim BLine As LLine
    4. Dim Splits() As String
    5. Dim Filenum As Integer
    6.  
    7. '"image":length:data...
    8. WS(Index).GetData IncomingData, vbString
    9.  
    10. Splits = Split(IncomingData, ":", 3, vbTextCompare)
    11. If Splits(0) = "image" Then
    12.     'just... dump it all in a file
    13.     Filenum = FreeFile
    14.     Open "C:\Draw.bmp" For Binary Lock Write As Filenum
    15.     Len(Splits(0)) + Len(Splits(1)) + 2)
    16.     ' put all data received into file, but make sure its only the stuff after "Image:length:"
    17.     Put Filenum, , Mid$(IncomingData, Len(Splits(0)) + Len(Splits(1)) + 3)
    18.     Close Filenum
    19.  
    20.     'set pic as picturebox
    21.     picMain.Picture = LoadPicture("C:\Draw.bmp")
    22. end if
    23. end function
    **not completely learned**
    Complete control of the registry ~

  4. #4
    PowerPoster
    Join Date
    Feb 2002
    Location
    Canada, Toronto
    Posts
    5,803

    Re: Sending Images With Winsock

    Quote Originally Posted by outcast24817
    Thanks, CVMichael. I can now send the image, but only the first ~8 KB arrives, do I have to set up my code to handle data coming in chunks, or what?
    Yes, that's exactly what you have to do, but I don't have time right now to write some code for you (I just arrived at work), I'll do it when i have some free time today.

    But the main problem I see:
    Actually, all the data gets sent, the data arrives in packets (4-8 KBytes/packet), the the DataArrival gets called several times.

    Only the FIRST time you create the image file, after that you just have to APPEND data to it until you get all the data (you get the size of the file first time).

  5. #5
    "Digital Revolution"
    Join Date
    Mar 2005
    Posts
    4,471

    Re: Sending Images With Winsock

    Quote Originally Posted by outcast24817
    Thanks, CVMichael. I can now send the image, but only the first ~8 KB arrives, do I have to set up my code to handle data coming in chunks, or what?

    Here is the receiving code:
    VB Code:
    1. Private Sub WS_DataArrival(Index As Integer, ByVal bytesTotal As Long)
    2. Dim IncomingData As String
    3. Dim BLine As LLine
    4. Dim Splits() As String
    5. Dim Filenum As Integer
    6.  
    7. '"image":length:data...
    8. WS(Index).GetData IncomingData, vbString
    9.  
    10. Splits = Split(IncomingData, ":", 3, vbTextCompare)
    11. If Splits(0) = "image" Then
    12.     'just... dump it all in a file
    13.     Filenum = FreeFile
    14.     Open "C:\Draw.bmp" For Binary Lock Write As Filenum
    15.     Len(Splits(0)) + Len(Splits(1)) + 2)
    16.     ' put all data received into file, but make sure its only the stuff after "Image:length:"
    17.     [B][COLOR=Red]Put Filenum, , Mid$(IncomingData, Len(Splits(0)) + Len(Splits(1)) + 3)[/COLOR][/B]
    18.     Close Filenum
    19.  
    20.     'set pic as picturebox
    21.     picMain.Picture = LoadPicture("C:\Draw.bmp")
    22. end if
    23. end function
    Also, you're overwriting all pre-existing data in the file.

    The 2nd argument of the Put statement is the offset (or starting byte) to put the data. The default is 1 (first byte).

    Try this for starters:

    VB Code:
    1. Dim lonOffset As Long
    2.  
    3. lonOffset = FileLen("C:\Draw.bmp") + 1
    4. Put Filenum, lonOffset, Mid$(IncomingData, Len(Splits(0)) + Len(Splits(1)) + 3)

  6. #6
    PowerPoster
    Join Date
    Feb 2002
    Location
    Canada, Toronto
    Posts
    5,803

    Re: Sending Images With Winsock

    Quote Originally Posted by DigiRev
    Try this for starters:

    VB Code:
    1. Dim lonOffset As Long
    2.  
    3. lonOffset = FileLen("C:\Draw.bmp") + 1
    4. Put Filenum, lonOffset, Mid$(IncomingData, Len(Splits(0)) + Len(Splits(1)) + 3)
    2 things:

    1) Don't use FileLen in the open statement, you might not get the correct size if the file is already opened... use LOF(FileNum), like this:
    VB Code:
    1. Put Filenum, [B]LOF(Filenum) + 1[/B], Mid$(IncomingData, Len(Splits(0)) + Len(Splits(1)) + 3)

    2) That line should be used ONLY the first time because only the first time you have a header...

    What I mean is:
    VB Code:
    1. ' This line the first time:
    2. Put Filenum, [B]LOF(Filenum) + 1[/B], Mid$(IncomingData, Len(Splits(0)) + Len(Splits(1)) + 3)
    3.  
    4. ' after the first time, you don't have a header to strip off the string anymore
    5. Put Filenum, [B]LOF(Filenum) + 1[/B], IncomingData
    So... this code should be used instead:
    VB Code:
    1. If LOF(Filenum) = 0 Then
    2.      Put Filenum, , Mid$(IncomingData, Len(Splits(0)) + Len(Splits(1)) + 3)
    3. Else
    4.      Put Filenum, LOF(Filenum) + 1, IncomingData
    5. End If

  7. #7
    "Digital Revolution"
    Join Date
    Mar 2005
    Posts
    4,471

    Re: Sending Images With Winsock

    Yea I kind of just scanned through the code and didn't really pay attention to the header, etc. Just noticed the Put statement was overwriting the file each time.

    You're right about the LOF though, don't know how that slipped past me.

  8. #8
    PowerPoster
    Join Date
    Feb 2002
    Location
    Canada, Toronto
    Posts
    5,803

    Re: Sending Images With Winsock

    There are 2 problems:
    First, I don't know why you have an Index for the socket when for the client you should have only one connection. If this is for the server (instead of client) then the code should be diferent. If it's the server then you have to give each file a unique name because otherwise you will write data from all clients into one file, and I'm sure you don't want that...

    Second: The next code you should use only for transfering the image file, if you transfer data other than the file, then you have to change the code for the other types of data. Since I don't know what else you transfer (how and what format), I could not write the code to support that also.

    OK, here is the code, I did not test it, but it should work:
    VB Code:
    1. Private Sub WS_DataArrival(Index As Integer, ByVal bytesTotal As Long)
    2.     Dim sData As String, Pos As Long
    3.    
    4.     ' make the variales static so the data gets preserved between calls
    5.     ' you can dim next variables in the
    6.     ' General Declarations section also (but remove next line if you do so)
    7.     Static DataLength As Long, FileNum As Integer
    8.    
    9.     '"image":length:data...
    10.     WS(Index).GetData sData, vbString
    11.    
    12.     ' first time, read header and open file
    13.     If DataLength = 0 And LCase(Left(sData, 6)) = "image:" Then
    14.         ' get the total data length
    15.         DataLength = Val(Split(sData, ":")(1))
    16.        
    17.         ' find the second ":"
    18.         Pos = InStr(1, sData, ":")
    19.         Pos = InStr(Pos + 1, sData, ":")
    20.        
    21.         ' get only the bitmap data (stip off the header)
    22.         sData = Mid$(sData, Pos + 1)
    23.        
    24.         FileNum = FreeFile
    25.         Open "C:\Draw.bmp" For Binary Lock Write As FileNum
    26.     End If
    27.    
    28.     ' save data into file
    29.     If DataLength > 0 And FileNum <> 0 Then
    30.         Put FileNum, LOF(FileNum) + 1, sData
    31.        
    32.         ' we received all the data that we are supposed to receive
    33.         If LOF(FileNum) >= DataLength Then
    34.             ' close the file, and reset variables
    35.             Close FileNum
    36.             DataLength = 0
    37.             FileNum = 0
    38.            
    39.             ' load picture
    40.             picMain.Picture = LoadPicture("C:\Draw.bmp")
    41.            
    42.             ' delete temporary picture file
    43.             Kill "C:\Draw.bmp"
    44.         Else
    45.     End If
    46. End Sub

  9. #9

    Thread Starter
    Lively Member outcast24817's Avatar
    Join Date
    Nov 2004
    Location
    USA
    Posts
    122

    Re: Sending Images With Winsock

    Thanks, CVMichael. That code worked perfectly.

    Sorry for the delayed reply.
    **not completely learned**
    Complete control of the registry ~

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width