Jump to content

TCPSend script stops if reciever buffer is full


 Share

Recommended Posts

Hi,

please help me out here. I've got 2 scripts where one transmits data via TCPSend() to the other.
The thing is, when the reciever doesn't do TCPRecv the sender just stops after a few chunks, I suppose that this is when the recievers buffer is full.

In my case the sender is a bigger server-script where major script pauses must not occur.
I've dumbed it down so you can try it easily. Run the Reciever first, then the sender. You'll notive that after 4 chunks or something the Sender will stop writing timestamps into the console.

Any ideas? One possible solution would be to make the server run an external script for every file transfer, but there may be better ones.
 

Reciever:

TCPStartup()
Global $Socket = TCPListen(@IPAddress1, 4466)
OnAutoItExitRegister("_Cleanup")

Global $Recieve ;Added

Do
    Sleep(100)
    $Accepted = TCPAccept($Socket)
Until $Accepted <> -1

MsgBox(0, "", "If this stays open, sender will stop sending.") ;Replaced Sleep with MsgBox

;The loop below should be run but won't as long something above is blocking (the MsgBox in this case).
While 1
    $Recieve = TCPRecv($Accepted, 5000)
WEnd


Func _Cleanup()
    TCPShutdown()
EndFunc

Sender:

TCPStartup()
Global $Socket = TCPConnect(@IPAddress1, 4466)
Global $BigString
OnAutoItExitRegister("_Cleanup")

For $i = 1 To 20000
    $BigString &= "x"
Next

While 1
    Sleep(500)
    TCPSend($Socket, $BigString)
    ConsoleWrite(@HOUR & ":" & @min & ":" & @SEC & @CRLF)
WEnd

Func _Cleanup()
    TCPShutdown()
EndFunc

 

Edited by Radiance
Link to comment
Share on other sites

Why make a Receiver without TCPRecv?

Haha I usually don't, the thing is that a client script might hang in a state where TCPRecv doesn't get called.
This is of course not intended but might happen for unforseen reasons and I'd like to intercept it even if it's unlikely.
 

Link to comment
Share on other sites

What are you sending anything to the client for if you're never going to receive it on the other end? You might as well send it to anywhere because your script does nothing. All you're doing is opening a socket, and accepting connections on it, you're not actually set up for receiving the data you're sending to it.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

A little modifying with some error checking -- works for me...

; Receiver

If Not TCPStartup() Then Exit
OnAutoItExitRegister("_Cleanup")

Global $MainSocket = TCPListen(@IPAddress1, 4466)
If @error Then Exit

Local $nSocket, $sRecv, $sData, $Timeout = 0

While 1
    Do
        Sleep(250)
        $nSocket = TCPAccept($MainSocket)
    Until $nSocket > 0

    While 1
        $sRecv = TCPRecv($nSocket, 4096)
        If @error Then
            ExitLoop
        ElseIf StringLen($sRecv) Then
            $sData &= $sRecv
            $Timeout = 0
        Else
            $Timeout += 1
            If $Timeout > 500 Then
                ExitLoop
            EndIf
        EndIf
        Sleep(10)
    WEnd

    TCPCloseSocket($nSocket)
    $Timeout = 0
    $sData = ''
WEnd

Func _Cleanup()
    TCPShutdown()
EndFunc
; Sender

If Not TCPStartup() Then Exit
OnAutoItExitRegister("_Cleanup")

Global $Socket = TCPConnect(@IPAddress1, 4466)
If @error Then Exit

Global $BigString, $EndGame = 0

For $i = 1 To 20000
    $BigString &= "x"
Next

While 1
    Sleep(500)
    TCPSend($Socket, $BigString)
    If @error Then ExitLoop
    ConsoleWrite(@HOUR & ":" & @MIN & ":" & @SEC & @CRLF)

    $EndGame += 1
    If $EndGame > 50 Then; <- prevents infinite loop (this script only)
        ConsoleWrite('--- DONE ---' & @CRLF)
        Sleep(2000); <- give some time for receiver before closing
        TCPCloseSocket($Socket)
        ExitLoop
    EndIf
WEnd

Func _Cleanup()
    TCPShutdown()
EndFunc

 

Edited by ripdad

"The mediocre teacher tells. The Good teacher explains. The superior teacher demonstrates. The great teacher inspires." -William Arthur Ward

Link to comment
Share on other sites

Hi,

thank you both for your responses.

I'm well aware that this example has no TCPRecv() function in it.
This was just for demonstrating such a case - imagine if the reciever script is starting to loop maybe because an AdLibRegister'd function or is being blocked by a MsgBox.
This happens during a very large datatransfer, for example transfering a bigger file in binary mode.

TCPRecv() can't get called, which was never intended but might happend and would stop the sender script completely if the buffer of the reciever runs full because the sender keeps sending data.

 

Link to comment
Share on other sites

I'm lost now. What exactly are you trying to demonstrate? What is the issue that you need to get around?

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

Sorry for the confusion.

I've changed the reciever one a bit to make it clear. Run the reciever - run the sender.

Sender writes timestamps to console after every chunk sent on the TCP socket.

Meanwhile the reciever should doing TCPRecv, which it can't, because it's hanging in MsgBox().
This could be anything blocking - Sleep(), an endless loop, whatever.

If the message box stays open long enough you'll notice that there are no more timestamps being written to console - the sender "hangs" in TCPRecv() because the reciever can't fit any more data in his buffer.

There could be other clients connected to the sender right now which can't communicate because of that one reciever that blocks.

To put it simple: how to change the sender so it continues writing timestamps to console without touching the reciever?

Edited by Radiance
Link to comment
Share on other sites

It's a good idea when working with the TCP functions, to make sure that
no blocking function interferes with communications. That said, if you
need those other functions, you'll have to come up with some other way
to handle it. Mainly, because it's not good to interrupt a file transfer,
since eventually a file will be corrupted, which I'm sure is not your goal.

Perhaps a separate script is in order here.

I would need more insight (code) to be of further help.

Edited by ripdad

"The mediocre teacher tells. The Good teacher explains. The superior teacher demonstrates. The great teacher inspires." -William Arthur Ward

Link to comment
Share on other sites

Honestly, it sounds like you need to set up some CoProcessing. Your other script(s), handing the CoProcessing, can be as dynamic or as simple as you need it, but it is a lot of work.

Edited by rcmaehl

My UDFs are generally for me. If they aren't updated for a while, it means I'm not using them myself. As soon as I start using them again, they'll get updated.

My Projects

WhyNotWin11
Cisco FinesseGithubIRC UDFWindowEx UDF

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...