Results 1 to 14 of 14

Thread: Winsock question...

  1. #1

    Thread Starter
    Super Moderator Wokawidget's Avatar
    Join Date
    Nov 2001
    Location
    Headingly Occupation: Classified
    Posts
    9,632

    Winsock question...

    When you send data using winsock the code execution carries on to the code once the data has been sent, regardless if it's been received or not by the server winsock connection.
    Is it possible, WITHOUT writting wrapper classes, to use the SendData sub like a function...ie, you send data, but code execution stops until the server app sends data back to the client winsock??

    Woka

  2. #2
    Registered User
    Join Date
    Mar 2004
    Location
    in a dirthole
    Posts
    117
    can't you have a timer control in there somewhere, and then when your waiting for data to come back have it loop in the timer control for data on that index only

  3. #3

    Thread Starter
    Super Moderator Wokawidget's Avatar
    Join Date
    Nov 2001
    Location
    Headingly Occupation: Classified
    Posts
    9,632
    You could do something like that, but it would be a cheap hack. You could not add something like that into a commercial app.
    I don't have an array of winsocks...as this is also bad coding for a commercial app. I spawn new threads in VB and have specialised connections in each thread.

    Woka

  4. #4
    Frenzied Member
    Join Date
    Aug 2000
    Location
    O!
    Posts
    1,177

    Re: Winsock question...

    Originally posted by Wokawidget
    When you send data using winsock the code execution carries on to the code once the data has been sent, regardless if it's been received or not by the server winsock connection.
    Is it possible, WITHOUT writting wrapper classes, to use the SendData sub like a function...ie, you send data, but code execution stops until the server app sends data back to the client winsock??

    Woka
    Make everything event driven. For example:
    1) A "Send" button click calls routine to connect to server.
    2) The Winsock_Connect event sub will build & send the request.
    3) The Winsock_DataArrival event sub will read the reply data and process it, then close the connection.
    If coded correctly, nothing will happen until an event occurs.

    Of course, this is a very simplistic example. What exactly do you want to do?

  5. #5
    I'm about to be a PowerPoster! kleinma's Avatar
    Join Date
    Nov 2001
    Location
    NJ - USA (Near NYC)
    Posts
    23,373

    Re: Winsock question...

    Originally posted by Wokawidget
    When you send data using winsock the code execution carries on to the code once the data has been sent, regardless if it's been received or not by the server winsock connection.
    Is it possible, WITHOUT writting wrapper classes, to use the SendData sub like a function...ie, you send data, but code execution stops until the server app sends data back to the client winsock??

    Woka
    perhaps you can divide the execting code into 2 subs (or functions) and call the one which sends the data via winsock, and then all the rest of the code to be executed put into the second sub/function. call it on the data arrival event of the winsock if the data coming back is the data you were waiting for... avoids the timers and loops

  6. #6
    Fanatic Member
    Join Date
    Feb 2003
    Location
    C:\Windows\Microsoft.NET\Framework
    Posts
    574
    What you're saying is implementation specific, meaning it is upto you. One implementation below:


    CLIENT

    Code:
    Private Sub Form_Load()
    
    Dim Subordinate As User
        
        Me.MousePointer = vbHourglass
        Call IResizesChildren_ResizeChildren
        BoolSubordinatesListReceived = False
        BoolJobTransferWindowRequestingConnection = True
        Call SendSubordinateListRequest
        Do
            DoEvents
            If BoolServerOffline Then
                BoolJobTransferWindowRequestingConnection = False
                Me.MousePointer = vbDefault
                Exit Sub
            End If
        Loop Until BoolSubordinatesListReceived Or BoolServerOffline
        
        If colSubordinates Is Nothing Then
            OurMessageBox "It is not possible to execute this task because there are currently no subordinates in your team." _
            , vbInformation, App.Title
            BoolSubordinatesListReceived = False
            Unload Me
            Exit Sub
        Else
            cboFromUser.Clear
            cboFromUser.AddItem vbNullString
            For Each Subordinate In colSubordinates
                cboFromUser.AddItem Subordinate.FullName
            Next Subordinate
            
            BoolSubordinatesListReceived = False
            Me.MousePointer = vbDefault
        End If
        
        
        
    End Sub
    
    
    
    Public Sub SendSubordinateListRequest()
    
    Dim StrMessageToSend As String
        
        StrMessageToSend = ComposeMessage(MgrSubordinatesRequest)
        Call mdiNew.SendMessageToServer(StrMessageToSend)
        
    End Sub
    
    
    Public Sub SendMessageToServer(ByVal StrMessageToSend As String)
    
    Dim LngTime As Long
    
        Internet.Connect
        BoolWinsockStillConnecting = True
        BoolServerOffline = False
        LngConnectionAttempts = 0
        LngTime = Timer
        
        Do
            LngConnectionAttempts = LngConnectionAttempts + 1
            If Wsock.State <> sckConnected Then
                If Wsock.State <> sckClosed Then Wsock.Close
                Wsock.Protocol = sckTCPProtocol
                Wsock.RemotePort = SERVER_PORT
                Wsock.RemoteHost = StrServerIPAddress
                Wsock.Connect
            End If
            
            Do
                DoEvents
                If BoolServerOffline Then BoolWinsockStillConnecting = False: Exit Sub
                If BoolForceQuit Then Call ExitApplication
            Loop Until Wsock.State = sckConnected Or Timer >= (LngTime + (LngConnectionAttempts * 5))
            
            If IsLoaded("frmLogin") Then Call frmLogin.ClearProgressBar
            If LngConnectionAttempts = 3 Then
                OurMessageBox "It is not possible to connect to the server at this time due to network congestion. Please try again later.", vbInformation, App.Title
                BoolWinsockStillConnecting = False
                If IsLoaded("frmLogin") Then frmLogin.Hide: BoolForceQuit = True: Call ExitApplication
                Exit Sub
            End If
        Loop Until Wsock.State = sckConnected
        
        BoolWinsockStillConnecting = False
        StrMessageToSend = PacketMessage(Encrypt(StrMessageToSend))
        Wsock.SendData StrMessageToSend
        
    End Sub



    SERVER

    Code:
    Private Sub WSock_DataArrival(Index As Integer, ByVal bytesTotal As Long)
    
    On Error GoTo ErrorDataArrival
    
    Dim StrMessageRecieved As String
    Dim StrMessageToSend As String
    Dim Arr() As String
    Dim I As Long
    Dim LngCounter As Long
    
        WSock(Index).GetData StrMessageRecieved, vbString
        StrMessageRecieved = UnpacketMessage(StrMessageRecieved)
        
        Arr = Split(StrMessageRecieved, PACKET_END)
        If UBound(Arr) < 0 Then Exit Sub
        For LngCounter = 0 To UBound(Arr)
            StrMessageRecieved = Arr(LngCounter)
            StrMessageRecieved = Decrypt(StrMessageRecieved)
            If Trim(StrMessageRecieved) = vbNullString Then GoTo NextMessage
            If Trim(StrMessageRecieved) <> vbNullString Then Set Message = ParseMessage(StrMessageRecieved)
            
            If Message Is Nothing Then GoTo NextMessage
            
            SocketPool(Index).UserName = Message.UserName
            
            MDI.sbrPrintMate.Panels("sbrpnlTransactionProgress").Text = GetMessageTypeString(Message.MessageType) & _
            " recieved from " & Message.UserName
            
            If Message.MessageType = DataBaseQuery Then
                Call SaveToRepository(Message.MessageData.DataBaseQuery.DataBaseQueryString, InBound, DataBaseQuery, Message)
            ElseIf Message.MessageType = LoginAuthRequest Or Message.MessageType = MgrSubordinatesRequest Then
                'Do nothing
            ElseIf Message.MessageType = UserProfileResponseReadReceipt _
            Or Message.MessageType = UserActiveStatusResponseReadReceipt _
            Or Message.MessageType = UserRightsResponseReadReceipt _
            Or Message.MessageType = DataBaseQueryReadReceipt Then
                Call ClearMessageFromRepository(OutBound, Message.MessageID, Message.UserName)
            ElseIf Message.MessageType = JobTransferRequest Then
                'Save the request to the database
                If Not SaveJobTransfer(Message.MessageData.JobTransferRequest.FromUser, _
                Message.MessageData.JobTransferRequest.ToUser, Message.UserName, _
                Message.MessageData.JobTransferRequest.CompanyList) Then
                    Debug.Print String(300, "=")
                    Debug.Print "Failed to save job transfer request in the database. Details of the job transfer request are: "
                    Debug.Print "From User: " & Message.MessageData.JobTransferRequest.FromUser
                    Debug.Print "To User: " & Message.MessageData.JobTransferRequest.ToUser
                    Debug.Print "Manager: " & Message.UserName
                    For I = 1 To Message.MessageData.JobTransferRequest.CompanyList.Count
                        Debug.Print Message.MessageData.JobTransferRequest.CompanyList.Item(LngCounter).CompanyName
                    Next I
                    Debug.Print String(300, "=")
                End If
                'The intimation to both users shall be given in the SynchronizeData method
            End If
            
            Set Reply = CreateReply(Message)
            StrMessageToSend = ComposeMessageString(Reply)
            
            MDI.sbrPrintMate.Panels("sbrpnlTransactionProgress").Text = "Sending " & GetMessageTypeString(Reply.MessageType) & _
            " to " & Reply.UserName
            
            If StrMessageToSend <> vbNullString Then
                StrMessageToSend = PacketMessage(Encrypt(StrMessageToSend))
                WSock(Index).SendData StrMessageToSend
                If Message.MessageType <> DataBaseQuery Then DoEvents
            End If
    NextMessage:
        
        Next LngCounter
        
        If BoolAutomaticallySynchronize Then Call SynchronizeData
        
    ErrorDataArrival:
    If Err <> 0 Then
        If Err = RECEIVED_DATA_AFTER_CLIENT_WENT_OFFLINE Then
            MDI.sbrPrintMate.Panels("sbrpnlTransactionProgress").Text = "Communication Error: " & _
            "The user " & SocketPool(Index).UserName & " has just gone offline. " & _
            "Cannot parse data received from the user. Data abandoned."
        End If
    End If
    
    End Sub

  7. #7

    Thread Starter
    Super Moderator Wokawidget's Avatar
    Join Date
    Nov 2001
    Location
    Headingly Occupation: Classified
    Posts
    9,632
    Good...but not good enough...while looping to see if data has been retrieved then your UI stops repainting

    I have code that does it, I just wanted to know if WINSOCK did it, WITHOUT writting code to loop it.

    I currently create another thread in VB and use that to send data and loop. Since it's in another thread then my main app can be repainted and doesn't look as if it's crashed.
    Using the SendMessage API halts the code execution until my thread returns the servers response.

    Woka

  8. #8
    Registered User
    Join Date
    Mar 2004
    Location
    in a dirthole
    Posts
    117
    sorry this is alittle off topic, but is this what i would need to do to have clients connect to a server app and such? i need to use winsock and threads... but dont know how

  9. #9
    Fanatic Member
    Join Date
    Feb 2003
    Location
    C:\Windows\Microsoft.NET\Framework
    Posts
    574
    >...while looping to see if data has been retrieved then your UI stops repainting

    That is not true. You don't actually need multithreading here, really, to be honest. A DoEvents does suffice, unless you want fine grained control over what the user must be allowed to do within that timeframe the data is being sent.

  10. #10
    Registered User
    Join Date
    Mar 2004
    Location
    in a dirthole
    Posts
    117
    I had read in a thread that using DoEvents in a winsock precedure is not recommended, it will cause winsock to be buggy or something i think.... bottom line is i heard it wasnt good to use
    plus doevents will just call a timer control if it's present, and time controls were said to work but it's not to be used for commercial apps, so doevents wont work

  11. #11
    I'm about to be a PowerPoster! kleinma's Avatar
    Join Date
    Nov 2001
    Location
    NJ - USA (Near NYC)
    Posts
    23,373
    Originally posted by krpto
    I had read in a thread that using DoEvents in a winsock precedure is not recommended, it will cause winsock to be buggy or something i think.... bottom line is i heard it wasnt good to use
    plus doevents will just call a timer control if it's present, and time controls were said to work but it's not to be used for commercial apps, so doevents wont work
    doevents would only cause a timer to fire if there was one.. which there is not.. i think you may have misread

  12. #12
    Fanatic Member
    Join Date
    Dec 2003
    Posts
    703
    Originally posted by Wokawidget
    Good...but not good enough...while looping to see if data has been retrieved then your UI stops repainting

    I have code that does it, I just wanted to know if WINSOCK did it, WITHOUT writting code to loop it.

    Woka
    Winsock has no built in support for what you want; try to work with winsock, not against it. If something isn't supported by winsock (I really mean the API/DLL here, not the rather basic functionality of the control), there's probably a good reason.

    You could do something like that, but it would be a cheap hack. You could not add something like that into a commercial app.
    I don't have an array of winsocks...as this is also bad coding for a commercial app. I spawn new threads in VB and have specialised connections in each thread.
    Hmm. Why is a multithreading solution any "better" than a winsock array? How do you do the I/O in the threads, control or API?

    Be wary of threads, e.g. a thread-per-connection model will scale extremely poorly..threads shouldn't be overused.
    an ending

  13. #13
    Member
    Join Date
    Feb 2004
    Posts
    46
    >>threads shouldn't be overused.
    Apparently, if you have too many more threads than processors, you lose a lot of performance from too many context switches (or something of the like... I'm just parroting something I heard.)

    >>Winsock has no built in support for what you want
    If you're talking about the DLL, I'm not sure if that's true, since with the C++ API calls, sockets are automatically put in 'blocking' mode when they're created. But, generally, you avoid blocking like the plague (i.e. you manually set the mode to asynchronous/non-blocking), which I suppose is why the VB control doesn't even support it. You'd be much better off making your own function/procedure to do background processing while periodically checking to see if the operation has completed.
    writing software in C++ is like writing software in VB, except that it's slower and harder and more frustrating and more finicky and doesn't give you nice convenient shortcuts on a silver platter. And it's better. *puts on heat-reflecting armor*

  14. #14
    Fanatic Member
    Join Date
    Dec 2003
    Posts
    703
    If you're talking about the DLL, I'm not sure if that's true, since with the C++ API calls, sockets are automatically put in 'blocking' mode when they're created.
    Yes, but for example a call to send() blocks until your supplied buffer has been accepted by winsock; the data has not necessarily been sent when the send() call returns. To have a function that doesn't return until a response has been received, you'd call a blocking send() followed by a blocking recv(). However, requiring such a function hints at the design of the program being less than optimal.
    an ending

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