AndSoW Posted January 2 Share Posted January 2 Hey, everybody! Sorry, my English is terrible!I am using TCPListen to establish a ws service, with the web client to test, the two can be normal connection handshake success, but the client to transmit the data, the server to TCPRecv unknown characters and garbled code? Can someone help me, please? Thank you, everybody! ---- The above is from translate client GET / HTTP/1.1 Host: 127.0.0.1:3001 Connection: Upgrade Pragma: no-cache Cache-Control: no-cache User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36 Upgrade: websocket Origin: http://www.emqx.io Sec-WebSocket-Version: 13 Accept-Encoding: gzip, deflate, br Accept-Language: zh-CN,zh;q=0.9 Sec-WebSocket-Key: nveB3rP7f2g6tH4YM9gwmA== Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits server HTTP/1.1 101 Switching Protocols Upgrade: WebSocket Connection: Upgrade Sec-WebSocket-Version: 13 Sec-WebSocket-Location: ws://127.0.0.1:3001 Sec-WebSocket-Accept: KyMUi4zyZa9ENlgXVEH01y5H62c= $rmsg = TCPRecv ($ConnectedSocket,4*1024) ConsoleWrite("ConsoleWrite:"&$rmsg) ConsoleWrite:亞5蠨?醬?? I found this on the forum, but it's still the same: Func WebSocketReceive($bytes) Return unmask(BinaryToString($bytes)) EndFunc Func unmask($text) Local $length = StringToBinary(StringMid($text, 2, 1)) $length = BitAND(Number($length), 127) Local $masks, $data If $length = 126 Then $masks = StringMid($text, 5, 4) $data = StringMid($text, 9) ElseIf $length = 127 Then $masks = StringMid($text, 11, 4) $data = StringMid($text, 15) Else $masks = StringMid($text, 3, 4) $data = StringMid($text, 7) EndIf Local $result = "" For $i = 0 To StringLen($data) - 1 $result &= Chr(BitXOR(Asc(StringMid($data, $i + 1, 1)), Asc(StringMid($masks, Mod($i, 4) + 1, 1)))) Next Return $result EndFunc Link to comment Share on other sites More sharing options...
Danp2 Posted January 2 Share Posted January 2 (edited) 3 hours ago, AndSoW said: ConsoleWrite("ConsoleWrite:"&$rmsg) What do you get if you change this to the following? ConsoleWrite("BinaryToString:" & BinaryToString($rmsg)) You may want to post a short reproducer script that we can run to observe the issue. For the proper way to post code, follow the instructions at the link. P.S. You may want to review this thread for some prior discussions on using a websocket client to handle the communications. Edited January 2 by Danp2 added PS Latest Webdriver UDF Release Webdriver Wiki FAQs Link to comment Share on other sites More sharing options...
AndSoW Posted January 2 Author Share Posted January 2 6 minutes ago, Danp2 said: What do you get if you change this to the following? ConsoleWrite("BinaryToString:" & BinaryToString($rmsg)) You may want to post a short reproducer script that we can run to observe the issue. For the proper way to post code, follow the instructions at the link. P.S. You may want to review this thread for some prior discussions on using a websocket client to handle the communications. After I tested the script with BinaryToString, the data sent back by the client was still a string of garbled code. I am here to see other authors code to test and learn:BY:milos83 Link to comment Share on other sites More sharing options...
AndSoW Posted January 2 Author Share Posted January 2 11 minutes ago, Danp2 said: What do you get if you change this to the following? ConsoleWrite("BinaryToString:" & BinaryToString($rmsg)) You may want to post a short reproducer script that we can run to observe the issue. For the proper way to post code, follow the instructions at the link. P.S. You may want to review this thread for some prior discussions on using a websocket client to handle the communications. Raw data:111111 BinaryToString:亰铫LK迵}z? BinaryToString:亞猒$煕n Link to comment Share on other sites More sharing options...
Danp2 Posted January 2 Share Posted January 2 37 minutes ago, Danp2 said: You may want to post a short reproducer script that we can run to observe the issue Back to this. We can only continue to guess at the problem without seeing your code. Latest Webdriver UDF Release Webdriver Wiki FAQs Link to comment Share on other sites More sharing options...
AndSoW Posted January 2 Author Share Posted January 2 (edited) 19 minutes ago, Danp2 said: Back to this. We can only continue to guess at the problem without seeing your code. expandcollapse popup#include <Array.au3> #include <Crypt.au3> TCPStartup() Global $gSocket = TCPListen("127.0.0.1", 3001) While True Local $client = TCPAccept($gSocket) If $client <> -1 Then Local $data = TCPRecv($client, 1024) If StringInStr($data, "Sec-WebSocket-Key:") Then ; Perform WebSocket handshake Local $key = StringRegExp($data, "Sec-WebSocket-Key: (.+)", 1)[0] ConsoleWrite($data & @CRLF) ConsoleWrite("$key:" & $key & @CRLF) Local $responseKey = base64(_Crypt_HashData($key & "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", $CALG_SHA1)) Local $response = "HTTP/1.1 101 Switching Protocols" & @CRLF & _ "Upgrade: websocket" & @CRLF & _ "Connection: Upgrade" & @CRLF & _ "Sec-WebSocket-Accept: " & $responseKey & @CRLF & @CRLF TCPSend($client, $response) ;Sleep(1000) ;WebSocketSend($client, "Hello!"); This works ;Sleep(1000) ; Now the connection is upgraded to WebSocket, handle communication While True Local $message = WebSocketReceive($client) If @error Then ContinueLoop If $message <> "" Then ; Handle the received message ConsoleWrite("Received message: " & $message & @CRLF) ;The received data here is an unknown character EndIf WEnd else ConsoleWrite("Received message: " & $data & @CRLF) ;The received data here is an unknown character EndIf EndIf WEnd Func WebSocketReceive($socket) Local $bytes = TCPRecv($socket, 4096) ; Adjust buffer size as needed If @error Or StringLen($bytes) = 0 Then Return SetError(1, 0, 0) ; Error reading data Return unmask(BinaryToString($bytes)) EndFunc Func WebSocketSend($socket, $message) Local $length = StringLen($message) Local $header = Chr(BitOR(0x80, 0x01)) ; FIN, Opcode Text If $length <= 125 Then $header &= Chr($length) ElseIf $length <= 65535 Then $header &= Chr(126) & Chr(BitShift($length, 8)) & Chr(BitAND($length, 0xFF)) Else $header &= Chr(127) For $i = 7 To 0 Step -1 $header &= Chr(BitShift($length, 8 * $i)) Next EndIf TCPSend($socket, $header & $message) EndFunc Func base64($vCode, $bEncode = True, $bUrl = False) Local $oDM = ObjCreate("Microsoft.XMLDOM") If Not IsObj($oDM) Then Return SetError(1, 0, 1) Local $oEL = $oDM.createElement("Tmp") $oEL.DataType = "bin.base64" If $bEncode then $oEL.NodeTypedValue = Binary($vCode) If Not $bUrl Then Return $oEL.Text Return StringReplace(StringReplace(StringReplace($oEL.Text, "+", "-"),"/", "_"), @LF, "") Else If $bUrl Then $vCode = StringReplace(StringReplace($vCode, "-", "+"), "_", "/") $oEL.Text = $vCode Return $oEL.NodeTypedValue EndIf EndFunc ;==>base64 Func unmask($text) Local $length = StringToBinary(StringMid($text, 2, 1)) $length = BitAND(Number($length), 127) Local $masks, $data If $length = 126 Then $masks = StringMid($text, 5, 4) $data = StringMid($text, 9) ElseIf $length = 127 Then $masks = StringMid($text, 11, 4) $data = StringMid($text, 15) Else $masks = StringMid($text, 3, 4) $data = StringMid($text, 7) EndIf Local $result = "" For $i = 0 To StringLen($data) - 1 $result &= Chr(BitXOR(Asc(StringMid($data, $i + 1, 1)), Asc(StringMid($masks, Mod($i, 4) + 1, 1)))) Next Return $result EndFunc test url :http://mqtt.uzyiot.com/ and https://www.lddgo.net/en/network/websocket Edited January 2 by AndSoW Link to comment Share on other sites More sharing options...
Danp2 Posted January 2 Share Posted January 2 I'm confused about your ultimate goal. Are you wanting to establish a connection to an existing Websocket server or are you trying to create a websocket server in AutoIt? Latest Webdriver UDF Release Webdriver Wiki FAQs Link to comment Share on other sites More sharing options...
AndSoW Posted January 2 Author Share Posted January 2 2 minutes ago, Danp2 said: I'm confused about your ultimate goal. Are you wanting to establish a connection to an existing Websocket server or are you trying to create a websocket server in AutoIt? trying to create a websocket server in AutoIt! TKS! Link to comment Share on other sites More sharing options...
Danp2 Posted January 2 Share Posted January 2 FWIW, your code works for me if I use a websocket client (in my case, I used Websocket Weasel) to connect to the URL ws://127.0.0.1:3001. Latest Webdriver UDF Release Webdriver Wiki FAQs Link to comment Share on other sites More sharing options...
AndSoW Posted January 2 Author Share Posted January 2 5 minutes ago, Danp2 said: FWIW, your code works for me if I use a websocket client (in my case, I used Websocket Weasel) to connect to the URL ws://127.0.0.1:3001. Can we see how you operate? I don't really understand:(in my case, I used Websocket Weasel) I tested ws with online html5 and what I received couldn't be parsed. I'm also looking for reasons and more ways to test results Link to comment Share on other sites More sharing options...
Danp2 Posted January 2 Share Posted January 2 I think that your HTML client is the issue. Websocket Weasel is a Firefox extension that lets you run a WS client directly in your browser. I should be the same thing as accessing https://mhgolkar.github.io/Weasel/. I also successfully tested with the client at https://websocketking.com/. Latest Webdriver UDF Release Webdriver Wiki FAQs Link to comment Share on other sites More sharing options...
AndSoW Posted January 2 Author Share Posted January 2 13 minutes ago, Danp2 said: I think that your HTML client is the issue. Websocket Weasel is a Firefox extension that lets you run a WS client directly in your browser. I should be the same thing as accessing https://mhgolkar.github.io/Weasel/. I also successfully tested with the client at https://websocketking.com/. TKS! After the test can indeed receive correctly:https://mhgolkar.github.io/Weasel/ It is possible that our browser language is causing the problem, it is possible that uft-8 is not getting gbk Link to comment Share on other sites More sharing options...
Danp2 Posted January 2 Share Posted January 2 My guess would be that it has something to do with the MQTT-compatible client behaving differently than a standard WS client. Latest Webdriver UDF Release Webdriver Wiki FAQs Link to comment Share on other sites More sharing options...
AndSoW Posted January 2 Author Share Posted January 2 12 minutes ago, Danp2 said: My guess would be that it has something to do with the MQTT-compatible client behaving differently than a standard WS client. My goal is to learn how to use AutoIt to build MQTT server after learning WS. Many projects are built on other people's platforms, and I try to build my own platform to control my own iot devices. Thank you very much for your patient reply. Please post the question for a few days first. After my testing here, not every time I successfully received the correct data, I will look for other answers. Or there's a better way! TKS! Link to comment Share on other sites More sharing options...
AndSoW Posted January 3 Author Share Posted January 3 This problem is really troubling, I can't get the data correctly at all, please ask for help! Link to comment Share on other sites More sharing options...
Solution Danp2 Posted January 3 Solution Share Posted January 3 On 1/2/2024 at 7:40 AM, AndSoW said: You may want to review this thread for some prior discussions on using a websocket client to handle the communications. Did you check out the thread I linked above? This would be the direction I would recommend, especially since AutoIt is single threaded and likely isn't capable of dealing with the complex communications required for WS / MQTT. Latest Webdriver UDF Release Webdriver Wiki FAQs Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now