?
Solved

Winsock in vb6

Posted on 2011-10-26
13
Medium Priority
?
1,477 Views
Last Modified: 2012-05-12
I wrote the following snip in vb6 and can't seem to make it work.

can someone look and tell my why DataArrival never does fire ?
Or if it does, no data is delivered ?

thanks


Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Private sTestRpt As String
Private bConnected As Boolean


Private Sub Command1_Click()
    Dim sSample As String
    
    Winsock2.LocalPort = 8001
    Winsock2.Listen
    
    'sTestRpt = GetFileContent(App.Path & "\TestRpt.txt")
    sTestRpt = String(300, ";")
    
    sSample = sTestRpt
    
    For I = 1 To 100
        SendFile sSample & vbCrLf
        
        Stop
    Next

End Sub

Public Function SendFile(sRpt As String)
    
    Winsock1.RemoteHost = "127.0.0.1"
    Winsock1.RemotePort = 8001
    Winsock1.Connect
    
    Do Until Winsock1.State = sckConnected
        DoEvents
        Sleep 100
    Loop
    
    Dim bRpt() As Byte
    'bRpt = sRpt
    'bRpt = StrConv(sRpt, vbFromUnicode)
    bRpt = StrConv(sRpt, vbFromUnicode) '' <--- This is OK to use, creates
    
    Sleep 100
    Winsock1.SendData bRpt '& vbCrLf
    'Winsock1.SendData sRpt & vbCrLf
    Sleep 100

    Winsock1.Close
    Do Until Winsock1.State = sckClosed
        DoEvents
    Loop
    
End Function

Private Sub Winsock1_Close()
    bConnected = False
End Sub

Private Sub Winsock1_Connect()
    bConnected = True

End Sub

Private Sub Winsock2_Close()
    Winsock2.Close
    DoEvents
    Winsock2.Listen
    
End Sub

Private Sub Winsock2_ConnectionRequest(ByVal requestID As Long)
    'This event gets called ...
    
    Winsock2.Close
    Winsock2.Accept requestID

End Sub

Private Sub Winsock2_DataArrival(ByVal bytesTotal As Long)
    'This event does not get called ...

    'Dim sStuff As String
    Dim bStuff() As Byte
    
    Winsock2.GetData bStuff, vbByte
    
    
    Me.Text1.Text = sStuff

End Sub

Open in new window

0
Comment
Question by:sidwelle
  • 5
  • 3
9 Comments
 
LVL 8

Expert Comment

by:Volox
ID: 37039883
Have you verified that you are getting through the ConnectionRequest method without an error?  And maybe it's a silly question, but have you checked that your event method is properly specified as the handler for that event for the control?

You may also be encountering problems because you are running both of these sockets within the same application.  It's been quite a while since I've done winsock programming in VB6 but it seems to me like there were issues with having multiple sockets talking to one another inside of the same application...  You are consuming the event handling thread by sending the data and event with the DoEvents you aren't truely releasing the thread and there are threads that the winsock needs to handle behind the scenes so it may just be a matter of the right processing resources not being available.  Like I say, this is a little fuzzy...  My first recommendation would be to split this into two seperate applications and see if it works that way, if you still have problems after that, then we know it's a deeper issue.
0
 

Author Comment

by:sidwelle
ID: 37041850
yes, and I use to write a lot of these myself, that’s why I can't figure out why this example won't work.

I wanted some to test on their system and let me know if I am chasing a problem with my code or my machine.

Thanks

0
 
LVL 8

Expert Comment

by:Volox
ID: 37041990
I'd totally test it out for you if I still had an environment with a VB6 compiler on it but I don't think I made an image of that old machine when I scrapped it a few years back.

Another thought occurred to me, for some reason I think I remember there being issues with using the localhost address... have you tried connecting to your network IP as apposed to localhost?
0
Cyber Threats to Small Businesses (Part 2)

The evolving cybersecurity landscape presents SMBs with a host of new threats to their clients, their data, and their bottom line. In part 2 of this blog series, learn three quick processes Webroot’s CISO, Gary Hayslip, recommends to help small businesses beat modern threats.

 

Author Comment

by:sidwelle
ID: 37168117
I've requested that this question be closed as follows:

Accepted answer: 250 points for Volox's comment http:/Q_27416902.html#37041990
Assisted answer: 0 points for sidwelle's comment http:/Q_27416902.html#37041850

for the following reason:

Thanks
0
 

Author Comment

by:sidwelle
ID: 37167849
No solutioins provided
0
 
LVL 1

Expert Comment

by:aloisiop1
ID: 37172558
I used to implement a array  of sockets. Every time your socket try to conect  will be created a new object.
Its very simple and the app can work with mutisocket....


'  AT FOR LOAD
    tcpServer(0).LocalPort = 8001
    tcpServer(0).Protocol = sckTCPProtocol
    tcpServer(0).Listen



Private Sub tcpServer_ConnectionRequest(Index As Integer, ByVal requestID As Long)
   
    If Index = 0 Then CnxNumber= CnxNumber+ 1
   
    If CnxNumber>= 32500 Then CnxNumber= 1

    Load tcpServer(CnxNumber)
       
    tcpServer(CnxNumber).Accept requestID
   
End Sub
0
 
LVL 8

Accepted Solution

by:
Volox earned 2000 total points
ID: 37193699
Finally found the ol' VB 6 environment and loaded up your sample code to work on it.  I found the solution(s).

1)  Your DataArrival method loads the data from the Winsock into the "bStuff" variable but writes out the "sStuff" variable (which you have commented out).  So that needs to be fixed (adding option explicit found this one pretty easily.  I also changed the method to append to the output instead of replace and you need a DoEvents after it in order for it to show up in the text box.

2) You don't need to do this to get it working, but I added output statements and error handling in order to track things down.

3) The problem is definitely induced in part by the fact that both sockets are running in the same process.  The root of the problem is that the socket that is sending data is closed before the socket that is receiving the data can process the receipt and the close of the socket supercedes the DataArrival.  So what happens here is that your Winsock1 writes data, and then snaps the socket closed and doesn't free up threading resources until the state of the socket has reached closed.  So under the covers the Winsock2 has the data in it's buffer but then gets the signal that the socket has closed.  So by the time a DoEvents would fire and let the VB thread handle the Winsock2 events, the closure has occurred and the buffer gets dumped and the Close event fires.  The solution was adding a DoEvents after the SendData method which then frees up the VB thread to allow Windsock2 to process the buffer before Winsock1 calls for the socket to close.

[Udpated code attached]

As I recall this was one of the key issues with hosting the server side of a winsock within an EXE because the threading model for a Standard EXE has a single thread for event handling.  I think if you encapulate your handling of the winsock within a DLL that is apartment threaded you can avoid these types of problems, but again, it's been so long since I've solved that kind of ugly problem that I don't recall if that is the precise fix of not.

Hope this gets you rolling.  Good luck with it.
Option Explicit

Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Private sTestRpt As String
Private bConnected As Boolean


Private Sub Command1_Click()
On Error GoTo ErrorHandler

    Dim sSample As String
    Dim I As Integer
    
    Me.Text1.Text = "Starting..." & vbCrLf
    DoEvents
    
    Winsock2.LocalPort = 8001
    Winsock2.Listen
    
    'sTestRpt = GetFileContent(App.Path & "\TestRpt.txt")
    sTestRpt = "123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"
    'String(300, ";")
    
    sSample = sTestRpt
    
    For I = 1 To 100
        SendFile sSample & vbCrLf
        
        'Stop
    Next

    Me.Text1.Text = Me.Text1.Text & "DONE." & vbCrLf
    DoEvents
    Exit Sub
    
ErrorHandler:
    Me.Text1.Text = Me.Text1.Text & "Command1 ERROR: " & Err.Number & " - " & Err.Description & vbCrLf
    DoEvents
End Sub

Public Function SendFile(sRpt As String)
    
    Winsock1.RemoteHost = "127.0.0.1"
    Winsock1.RemotePort = 8001
    Winsock1.Connect
    
    Do Until Winsock1.State = sckConnected
        DoEvents
        Sleep 100
    Loop
    
    Me.Text1.Text = Me.Text1.Text & "Winsock 1 Connected." & vbCrLf
    DoEvents
    
    Dim bRpt() As Byte
    'bRpt = sRpt
    'bRpt = StrConv(sRpt, vbFromUnicode)
    bRpt = StrConv(sRpt, vbFromUnicode) '' <--- This is OK to use, creates
    
    Sleep 100
    Winsock1.SendData bRpt '& vbCrLf
    'Winsock1.SendData sRpt & vbCrLf
    DoEvents
    Sleep 100

    Winsock1.Close
    Do Until Winsock1.State = sckClosed
        DoEvents
    Loop
    
    Me.Text1.Text = Me.Text1.Text & "Send Completed." & vbCrLf
    DoEvents
End Function


Private Sub Winsock1_Close()
    bConnected = False
End Sub

Private Sub Winsock1_Connect()
    bConnected = True

End Sub

Private Sub Winsock2_Close()
    Me.Text1.Text = Me.Text1.Text & "Winsock 2 CLOSED." & vbCrLf
    DoEvents
    
    Winsock2.Close
    DoEvents
    Winsock2.Listen
    
End Sub

Private Sub Winsock2_ConnectionRequest(ByVal requestID As Long)
On Error GoTo ErrorHandler
    'This event gets called ...
    
    Winsock2.Close
    Winsock2.Accept requestID
    
    Me.Text1.Text = Me.Text1.Text & "Connection Request Recvd." & vbCrLf
    DoEvents
    Exit Sub
    
ErrorHandler:
    Me.Text1.Text = Me.Text1.Text & "ConnectionRequest ERROR: " & Err.Number & " - " & Err.Description & vbCrLf
    DoEvents
End Sub

Private Sub Winsock2_DataArrival(ByVal bytesTotal As Long)
On Error GoTo ErrorHandler

    Dim sStuff As String
    'Dim bStuff() As Byte
    
    Winsock2.GetData sStuff, vbByte
    
    
    Me.Text1.Text = Me.Text1.Text & sStuff
    DoEvents
    Exit Sub
    
ErrorHandler:
    Me.Text1.Text = Me.Text1.Text & "DataArrival ERROR: " & Err.Number & " - " & Err.Description & vbCrLf
    DoEvents
End Sub

Open in new window

0
 

Author Comment

by:sidwelle
ID: 37198000
Thanks for following up, I will take another look at it the first of this week.  
0
 

Author Closing Comment

by:sidwelle
ID: 37222301
Volox,   It was the doEvents after the send.  After I added this after the Send function all started to work.  I was even able to remove all the sleep(s) and run it as fast as it would go.

Thanks

Sorry I took so long to get back to you.
0

Featured Post

Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article will inform Clients about common and important expectations from the freelancers (Experts) who are looking at your Gig.
In real business world data are crucial and sometimes data are shared among different information systems. Hence, an agreeable file transfer protocol need to be established.
The purpose of this video is to demonstrate how to set up the WordPress backend so that each page automatically generates a Mailchimp signup form in the sidebar. This will be demonstrated using a Windows 8 PC. Tools Used are Photoshop, Awesome…
Progress

850 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question