Jump to content
Sign in to follow this  
tsolrm

TCPSend

Recommended Posts

tsolrm

I've got a server that receives messages from multiple clients. (something like a chat)

The client reads the first N amount of characters of the message received from the server and decides what type of message is it and what to do with it.

The problem is that sometimes when I use SendAll like this

Func SendAll ($Rec)

For $i=1 to Ubound ($Socket)-1

TCPSend ($Socket [$i], $Rec)

Next

EndFunc

SendAll ($text)

Sleep (500)

$text2="some info "&$Challenger&", "&StringTrimRight ($Team1Chat,2)

SendAll ($text2)

Sleep (500)

$text3="someinfo "&$Challenged&", "&StringTrimRight ($Team2Chat,2)

SendAll ($text3)

$Challenges[$Game] = "|"&$Challenger&"|"&$Team1&"<=>|"& $Challenged&"|"&$Team2

Sleep (500)

If i don't use Sleep in between - the messages end up glued together. So the client doesn't receive them as separate messages but as one. This messes up the "The client reads the first N amount of characters of the message received from the server and decides what type of message is it and what to do with it."

And I can't use sleep because i can't have the server sleeping for 0.5 sec every time it needs to send a bunch of messages.

Any solution please?

Share this post


Link to post
Share on other sites
ProgAndy

You should create a proper protocol: Each packet has the same header, e.g. 1 byte Packet-type, 4 byte Packet-Size and then its content. Read the amount of data specified in size, process and proceed to the next packet.

Edited by ProgAndy

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Share this post


Link to post
Share on other sites
tsolrm

You should create a proper protocol: Each packet has the same header, e.g. 1 byte Packet-type, 4 byte Packet-Size and then its content. Read the amount of data specified in size, process and proceed to the next packet.

Yeah I don't have that - I have plain text. I wouldn't mind reworking everything but i do not know how to do this. I've never dealt with packets.

Could u give an example and a reasonable explanation please?

Share this post


Link to post
Share on other sites
ProgAndy

I think, it should work like this but I did not test it:

_PacketSend($socket, 12, StringToBinary("Mein Paket", 4))

$data = _PacketRecv($socket2)
$type = @extended
If $type = 12 Then
    ConsoleWrite(BinaryToString($data, 4) & @LF)
Else
    ConsoleWrite("Type: " & $type & " - " & $data &@LF)
EndIf


; #FUNCTION# ====================================================================================================================
; Name ..........: _PacketSend
; Description ...:
; Syntax ........: _PacketSend($hSocket, $iType, $vData)
; Parameters ....: $hSocket          - A handle value.
;                 $iType               - An integer value. (0-255)
;                 $vData               - A variant value, binary recommended
; Return values .: same as TCPSend
; Author ........: ProgAndy
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func _PacketSend($hSocket, $iType,$vData)
    Local $iLen = Binary(Int(BinaryLen($vData),1))
    Local $r = TCPSend($hSocket, Binary(Chr($iType)) & $iLen & Binary($vData))
    Return SetError(@error, @extended, $r)
EndFunc

; #FUNCTION# ====================================================================================================================
; Name ..........: _PacketRecv
; Description ...:
; Syntax ........: _PacketRecv($hSocket)
; Parameters ....: $hSocket          - A handle value.
; Return values .: data sent in packet as binary, or nothing on error
; Author ........: ProgAndy
; Modified ......:
; Remarks .......:
; Related .......:
; Link ..........:
; Example .......: No
; ===============================================================================================================================
Func _PacketRecv($hSocket)
    Local $type
    Do
        $type = TCPRecv($hSocket, 1, 1)
        If @error Then Return SetError(1, 0, Binary(""))
    Until $type
    $type = Int($type)
    Local $iRecvLen = 0, $iLen = Binary(""), $bChunk

    Do
        $bChunk = TCPRecv($hSocket, 4-$iRecvLen, 1)
        If @error Then Return SetError(2, 0, Binary(""))
        If $bChunk Then
            $iLen &= $bChunk
            $iRecvLen = BinaryLen($iLen)
        EndIf
    Until $iRecvLen = 4
    $iLen = Number($iLen, 1)

    Local $iRecvLen = 0, $bRecv = Binary("")
    Do
        $bChunk = TCPRecv($hSocket, $iLen-$iRecvLen, 1)
        If @error Then Return SetError(2, 0, $bRecv)
        If $bChunk Then
            $bRecv &= $bChunk
            $iRecvLen = BinaryLen($iLen)
        EndIf
    Until $iRecvLen = $iLen
    SetExtended($type)
    Return $bRecv

EndFunc

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Share this post


Link to post
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
Sign in to follow this  

×