Announcement

Collapse
No announcement yet.

TCP Server multi-threading (New topic)

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Michael Mattias
    replied
    So I'm thinkign I'll have to do the polling method ...Still foggy on this one...not sure why
    You never "have to" poll.

    If you are trying to set up a TCP function to "run until complete" and execute in its own thread of execution, I don't know what it is you want to know when that thread function completes; i.e., I can't tell from your code snippet what you are trying to do.

    It 'appears' you might be trying to maintain some kind of 'user count' (???).

    If so, you can use something like Win32: Memory Mapped Files/Control User Count April 26, 2001.

    That demo was created to work across processes, but no reason you can't do the same kind of thing across threads

    Or maybe you want to make sure all thread functions have completed before you allow the program to end? That's where you would use WFMO (with "all = true") against an array of thread handles.


    A paragraph of explanation would help; that should get you some ideas, anyway.

    MCM

    Leave a comment:


  • Scott Turchin
    replied
    It's local
    Local hThread As Long

    So I'm thinkign I'll have to do the polling method - I'll check your sample out..

    Still foggy on this one...not sure why...

    Leave a comment:


  • Michael Mattias
    replied
    >How do I get around that then, without using a global variable
    Code:
    Call CreateNewConnectionThread(tcpCount)  [b]TO hthread[/b]
    (hthread LOCAL or STATIC)
    ????

    Or, take a look at how I handled (no pun intended) open thread handles in this demo:
    GUI + Worker Thread + Abort Demo 11-24-07

    Basically, you return the thread handle (still open) to whatever procedure needs it. Thread handles do not automatically close when the thread function completes.

    If the handle is still open, you can use it in the WFSO and WFMO functions. (else you get the dreaded "INVALID_PARAMETER" error from Windows, which tells you not much at all).

    MCM
    PS: Another example of why I believe PB wishes they had used the syntax "THREAD CLOSE HANDLE" instead of just "THREAD CLOSE"
    Last edited by Michael Mattias; 11 Oct 2008, 10:17 AM.

    Leave a comment:


  • Scott Turchin
    replied
    How do I get around that then, without using a global variable - that thread creates the modeless dialog box, so I want to wait.

    After doing more searching and reading it appears I "Should" be able to use the WaitForSingleObject API (??)..

    I could always do a sleep 10000 but that's not proper, the connection should never last more than 10 seconds unless someone is on 14.4k dialup....

    Leave a comment:


  • Michael Mattias
    replied
    >Thread Close hThread To lResult
    >Function = hThread 'grab thread handle to close prematurely and properly if need

    THREAD CLOSE closes and invalidates the handle.

    If you need the handle in your calling procedure, don't close it!!

    Leave a comment:


  • Scott Turchin
    replied
    Determined my thread is closing before anything can happen - Michael I know you've preached about doing this properly but I never understood Waitforsingleobject.

    IN this case per MS because I have a window with messages I have to use MsgWaitforMultipleOjbects.

    I don't understand how that works exactly.

    But I tried this, and it locked up my machine LOL Temporarily that is.

    help?

    Code:
    Function CreateNewConnectionThread(ByVal tcpCount As Long) As Long
    Local hThread   As Long
    Local lResult As Long
    
    Thread Create ConnectionThreadProc(ByVal tcpCount) To hThread
    Do Until lResult = %WAIT_TIMEOUT
        lResult = MsgWaitForMultipleObjects(1,hThread,%TRUE,5000,%QS_TIMER Or %QS_ALLINPUT)
    Loop
    Thread Close hThread To lResult
    Function = hThread 'grab thread handle to close prematurely and properly if need be.
    End Function

    Leave a comment:


  • Scott Turchin
    started a topic TCP Server multi-threading (New topic)

    TCP Server multi-threading (New topic)

    John - Michael - since you got me on the topic I went ahead and tried this, I like the idea of it but I'm not getting my %FD_READ

    If I do a CASE ELSE where %FD_READ is at, I get 4 "Msgbox"'s (I use those for debugging)....the browser says "Waiting for reply.."....

    I do record a connection, I do get as far as the INITDIALOG in the modeless dialog box....but that's it..

    Code:
    This first bit of code is from my main modal dialogProc call back function:
    
            g_nServertcp = FreeFile
            Tcp Open Server Addr nServerIP Port g_Port As g_nServertcp TimeOut g_TimeOut
            If Err Then
                sTmp = "Couldn't create socket!"
                Control Set Text CbHndl,%IDLABEL1, sTmp
            Else
                'What's the next TCP Count
                Tcp Notify g_nServertcp, Accept To g_hDlg As %TCP_ACCEPT
                sTmp = "Listening on " & g_ServerIP & ":" & Format$(g_Port)
                Control Set Text CbHndl,%IDLABEL1, sTmp
            End If
            Function = %TRUE
    
        Case %TCP_ACCEPT
            Select Case Lo(Word, CbLParam)
                Case %FD_ACCEPT 'Create the new thread here
                    Incr tcpCount
                    Call CreateNewConnectionThread(tcpCount)
                    Control Set Text CbHndl,%IDCONNLABELTL, Format$(tcpCount,"")
                    Function = %TRUE
            End Select
                          
         Case %WM_DESTROY
             Tcp Close g_nServertcp
             KillTimer CbHndl, %IDT_TIMER1
             Shell_NotifyIcon %NIM_DELETE, ti
             DestroyIcon ti.hIcon     
    
    
    '============================================<tcpThreadProc>===============================================================
    Function CreateNewConnectionThread(ByVal tcpCount As Long) As Long
    Local hThread   As Long
    Local lResult As Long
    
    Thread Create ConnectionThreadProc(ByVal tcpCount) To hThread
    Thread Close hThread To lResult
    'WaitForSingleObject hThread,%INFINITE
    Function = hThread 'grab thread handle to close prematurely and properly if need be.
    End Function
    '==========================================================================================
    Function ConnectionThreadProc(ByVal tcpCount As Long) As Long
    Local tDlg As Long
    Local lResult As Long
    Dialog New 0, "",,, 1,1, %WS_POPUP Or %WS_DLGFRAME  To tDlg 'modeless
    Dialog Show Modeless tDlg Call ConnectProc To lResult
    End Function
    '==========================================================================================
    CallBack Function ConnectProc() As Long
    Local sBuffer   As String
    Local sPacket   As String
    Local Header    As String
    Static hTcp     As Dword
    Local lHost     As String
    Local lResult   As Long
    
    
    Select Case CbMsg
        Case %WM_INITDIALOG
            hTcp = %INVALID_SOCKET
            hTcp = FreeFile
            Tcp Accept g_nServertcp As hTcp
            Tcp Notify hTcp, Recv Close To CbHndl As %TCP_ECHO
            Function = %TRUE
    
        Case %TCP_ECHO
            Select Case Lo(Word, CbLParam)
                Case %FD_READ
                    If hTcp <> %INVALID_SOCKET Then
                        'Grab client IP and insert here
                        lHost = RemoteIp(ByVal hTcp)
                        AppendTextToWindow g_txtHandle, TimeStamp() & " Connection established from: " & lHost
                        ' Perform a receive-loop until there is no data left (ie, the end of stream)
    '                sBuffer = ""
    '                sPacket = ""
                        Do
                          Tcp Recv hTcp, 1024, sBuffer
                          sPacket = sPacket + sBuffer
                          If Len(sPacket) > 4096 Then Exit Do 'Buffer overflow prevention
                        Loop Until sBuffer = "" Or IsTrue Eof(hTcp) Or IsTrue Err
                        sPacket = Left$(sPacket,Len(sPacket)-2) & String$(50,"-")
                        lResult = ParseAndUpdateLogfile(ByVal sPacket,ByVal hTcp) 'Updates window
                    ' <-------------Send data and disconnect------------->
                        If IsFalse lResult Then 'html
                            Header = "HTTP/1.1 200" & $CrLf
                            Header = Header & "Server: " & g_szMine & $CrLf
                            Header = Header & "Date: " & GetPCTimeandDate() & $CrLf
                            Header = Header & "Content-Type: text/html" & $CrLf
                            Header = Header & "Content-Length: " & Format$(Len(g_BBSDown)) & $CrLf
                            Tcp Send hTcp, Header & $CrLf
                            Tcp Send hTcp, g_BBSDown
                        Else 'jpg
                            Header = Header & "HTTP/1.1 200" & $CrLf
    '                        Header = Header & "Last-Modified: " & GetFileDateandTime(g_BBSDownImageFile) & " GMT" & $CrLf
                            Header = Header & "Server: " & g_szMine & $CrLf
                            Header = Header & "Date: " & GetPCTimeandDate() & $CrLf
                            Header = Header & "Content-Type: image/jpeg" & $CrLf
                            Header = Header & "Content-Length: " & Format$(Len(g_BBSDownImage)) & $CrLf
                            Header = Header & "Accept-range: bytes"  & $CrLf 'or something like that.
                            Header = Header & "Connection: close" & $CrLf
                            Tcp Send hTcp, Header & $CrLf
                            Tcp Send hTcp, g_BBSDownImage
                        End If
                        Tcp Close hTcp
                        hTcp = %INVALID_SOCKET
                        Dialog End CbHndl,%TRUE
                    ' <-------------Send data and disconnect------------->
                    'End connection here
                    End If
    
                Case %FD_CLOSE
                    Tcp Close hTcp
                    hTcp = %INVALID_SOCKET
            End Select
    End Select
    End Function
    '==========================================================================================
Working...
X