Socket Class - 2022/09/07 - beta.8

Post your working scripts, libraries and tools.
User avatar
TheArkive
Posts: 1027
Joined: 05 Aug 2016, 08:06
Location: The Construct
Contact:

Socket Class - 2022/09/07 - beta.8

20 Oct 2020, 16:06

Thanks to @GeekDude and @Bentschi for their work here. This is my version, fixed up for AHK v2.

:arrow: Download on GitHub

This is just a basic socket layer. No encryption is included with this library. I plan to create an OpenSSL wrapper in a separate lib.

The included example script does the following:
  • Creates a GUI
  • Opens a TCP listening port on 0.0.0.0:27015
  • Connects to that port from 127.0.0.1
  • Sends an HTTP request (that doesn't do anything)
  • Displays the text read by the "listener" socket (should be the same as what was sent)
  • Closes ports after this simple operation concludes
=================================================
Updates
=================================================

To-Do:
  • Add multi-cast capability
Last edited by TheArkive on 07 Sep 2022, 12:43, edited 2 times in total.
User avatar
TheArkive
Posts: 1027
Joined: 05 Aug 2016, 08:06
Location: The Construct
Contact:

Re: Socket Class - 2021/10/13 - beta.1

13 Oct 2021, 14:32

2021/10/13
  • updated for beta.1
  • restructured callback mechanics (nothing too special)
  • improved example
  • added classes for handling structs
  • all "primary" error codes are now 1 for success and 0 for failure
    call obj.WsaLastErr() for extended error info
  • added error code constants, and several other constants
  • simplified methods to just handle buffers (no SendText/RecvText)
  • added .AddrToStr() method to get socket address info.
viv
Posts: 217
Joined: 09 Dec 2020, 17:48

Re: Socket Class - 2021/10/13 - beta.1

16 Jul 2022, 23:46

Hello, there seems to be an error in 2.0 beta7

I added a test send function like this to the example
Works fine before beta7
but in beta7 there is an error

Code: Select all

test_send()
{
    sock := winsock("client", cb, "IPV4")
    sock.Connect("127.0.0.1", 27015)
    msg := "abc"
    strbuf := Buffer(StrLen(msg) * 3) //I dont khow how to set the buffer length...But it should not be where the error occurs (probably)
    StrPut(msg, strbuf, "UTF-8")
    sock.Send(strbuf)
}
It receives the data, but also gives an error
123.jpg
123.jpg (38.68 KiB) Viewed 5389 times

viewtopic.php?f=24&t=95688#p472447
It probably has something to do with these
Fixed Buffer.Size to avoid reallocating if size is unchanged.
Fixed Buffer causing undefined behaviour if resized to 0.
User avatar
TheArkive
Posts: 1027
Joined: 05 Aug 2016, 08:06
Location: The Construct
Contact:

Re: Socket Class - 2021/10/13 - beta.1

17 Jul 2022, 00:32

The only way I can replicate your issue is on 32-bit ahk. 64-bit works fine. Maybe i got some offsets wrong somewhere. I'm looking into it.

EDIT:

My first x64 test worked fine, but now I'm getting the error on x64 also. It's just a 0 length buffer. Which makes sense to throw such an error. I'm still trying to figure out why the read event reads 0 bytes.

There is also no error data at all in the coming from winsock, so this technically isn't an issue. It looks like I just didn't write in any means to handle a receive event that reads zero bytes. I'm still trying to figure out a case where zero bytes is sent, and what in general causes it.

@viv

I think I found the issue. This little socket lib is setup to be 100% async. But you are not the first person i've seen trying to use it as "blocking" at the "connect" phase, which does make sense to have such an option.

So the issue comes down to timing. This actually "fixes" the issue:

Code: Select all

test_send()
{
    sock := winsock("client", cb, "IPV4")
    sock.Connect("127.0.0.1", 27015)
    sleep 1000 ; <------------------------- gotta pause, then send
    msg := "abc"
    strbuf := Buffer(StrLen(msg) * 3)
    StrPut(msg, strbuf, "UTF-8")
    sock.Send(strbuf)
}

I'm not sure what was causing the 0-length buffer, but it seems to be as a result of how/when the msg is sent in your test func.

So, I've been thinking about adding a means to make the Connect() method blocking as an option. Doing this would make your example work just fine. I'll bump this up on my priority list, and try to put some better "toggle blocking" options in this lib.

EDIT:

In an async context, normally you would put your commands to send a message separate from the commands that open the socket, because that's how async works. It depends on the msgs/signals sent. Technically the coder is supposed to wait for the FD_WRITE signal (within the callback) before sending something. FD_WRITE means "ok I'm ready to send a msg now". So your little error was just a result of sending the message early, and then for some reason an extra packet with 0 bytes to read was also sent, and my example wasn't setup to handle that.

So, yah, this lib needs to be "blocking friendly".
viv
Posts: 217
Joined: 09 Dec 2020, 17:48

Re: Socket Class - 2021/10/13 - beta.1

17 Jul 2022, 01:31

@TheArkive

Thank you.
I don't quite understand the details of how it works
But I do understand part of it ....

I have no requirement for the real-time nature of the messages
So sleep(1000) is an acceptable solution for me

I can control my own send message script
But I can't control the other send message APPs

I use this library as an android control PC
On the PC
I use this library to listen for messages
On Android
I use the following app
https://play.google.com/store/apps/details?id=com.asif.plugin.sendexpect&hl=en_US&gl=US

It sends a message to the PC and then the PC executes different commands based on the message

The above error also occurs when sending messages in the app
I'm currently ready to roll back to 2.0 beta 6...
Or temporarily ignore the error with try...
User avatar
TheArkive
Posts: 1027
Joined: 05 Aug 2016, 08:06
Location: The Construct
Contact:

Re: Socket Class - 2021/10/13 - beta.1

17 Jul 2022, 01:34

Yah, when you're trying to send something with this lib, and if you are not doing so in the context of the callback, you'll continue to get this error, until I finally make blocking accessible in this lib.
User avatar
TheArkive
Posts: 1027
Joined: 05 Aug 2016, 08:06
Location: The Construct
Contact:

Re: Socket Class - 2022/07/19 - beta.7

19 Jul 2022, 13:19

2022/07/19
  • Setup a mechanism to try every addr structure from GetAddrInfo() when needed. The loop continues until a successful connection completes.
  • condensed some code
  • Added AddrToStr() method
  • Added support for creating blocking sockets. By default all sockets are non-blocking. See examples.
@viv

I managed to make your example more reliably functional. Please see updated examples. Part of the fix is to handle a zero-length buffer on the receive event.
viv
Posts: 217
Joined: 09 Dec 2020, 17:48

Re: Socket Class - 2022/07/19 - beta.7

20 Jul 2022, 05:15

@TheArkive

Thanks, now work fine

UTF-8 is defined to encode code points in one to four bytes
So the buff size that may be compatible with all characters should be set to StrLen(msg) *4 ?
in my case(CJK),3 bytes for common characters are probably enough,so i set it StrLen(msg) *3
it's not a big deal
https://en.wikipedia.org/wiki/UTF-8

have a nice day
User avatar
TheArkive
Posts: 1027
Joined: 05 Aug 2016, 08:06
Location: The Construct
Contact:

Re: Socket Class - 2022/07/19 - beta.7

20 Jul 2022, 08:00

Actually i can change that to be better. You can use StrPut() to get the actual str size (including null) at specified encoding, not just UTF8.

@viv

Example updated with StrPut() to get actual string size. And I put multi-byte characters in there so you can see the full msg is sent.

No need to allocate extra space "just in case" when you can get the exact size.
vanheartnet098
Posts: 61
Joined: 01 Sep 2020, 09:49

Re: Socket Class - 2022/07/19 - beta.7

28 Jul 2022, 09:39

Can this work in autohotkey version 1.1.33 ?
User avatar
TheArkive
Posts: 1027
Joined: 05 Aug 2016, 08:06
Location: The Construct
Contact:

Re: Socket Class - 2022/07/19 - beta.7

28 Jul 2022, 10:15

vanheartnet098 wrote:
28 Jul 2022, 09:39
Can this work in autohotkey version 1.1.33 ?

No, not without (most likely) significant modification. The work I based this script on is from a v1 version though. See the first post, first sentence.
vanheartnet098
Posts: 61
Joined: 01 Sep 2020, 09:49

Re: Socket Class - 2022/07/19 - beta.7

29 Jul 2022, 08:57

TheArkive wrote:
28 Jul 2022, 10:15
No, not without (most likely) significant modification. The work I based this script on is from a v1 version though. See the first post, first sentence.
Do you know any other than this socket.ahk? Cant find anything in this forum that will help me complete my script.
User avatar
TheArkive
Posts: 1027
Joined: 05 Aug 2016, 08:06
Location: The Construct
Contact:

Re: Socket Class - 2022/07/19 - beta.7

29 Jul 2022, 09:14

vanheartnet098 wrote:
29 Jul 2022, 08:57
Do you know any other than this socket.ahk? Cant find anything in this forum that will help me complete my script.

Sorry to say it, but no, I don't. socket.ahk as I recall doesn't have much in the way of examples, but it still works. But even if it did have examples, ya gotta read up on Winsock2, and ya need to know the different approach between "blocking" and "non blocking".

The main things that needs to change in my script to be v1 compatible is Buffer() changes to VarSetCapacity. And...

Code: Select all

func_or_method => expr

... changes to ...

func_or_method {
    expr
}
vanheartnet098
Posts: 61
Joined: 01 Sep 2020, 09:49

Re: Socket Class - 2022/07/19 - beta.7

29 Jul 2022, 11:36

TheArkive wrote:
29 Jul 2022, 09:14

Sorry to say it, but no, I don't. socket.ahk as I recall doesn't have much in the way of examples, but it still works. But even if it did have examples, ya gotta read up on Winsock2, and ya need to know the different approach between "blocking" and "non blocking".
Alright, thanks, i will try and change those, hope can make it work this time 😆.
vanheartnet098
Posts: 61
Joined: 01 Sep 2020, 09:49

Re: Socket Class - 2022/07/19 - beta.7

24 Aug 2022, 04:59

@TheArkive

I managed to make it work somehow, But , how can i fix the socket causing the script to "Not responding" for 5-10secs after Connect() function failed. I want it that it just exit or do nothing when it failed.

Thanks in advance
User avatar
TheArkive
Posts: 1027
Joined: 05 Aug 2016, 08:06
Location: The Construct
Contact:

Re: Socket Class - 2022/07/19 - beta.7

25 Aug 2022, 00:49

@vanheartnet098
You need to use non-blocking means to prevent the app from freezing. There is an example included that shows how to handle (or at least detect) a failed connection. It's all the way at the bottom of the cb() function (that is the callback in the example).

I'm sorry to say it, but non-blocking is not easy to use.

You must define a callback func, and in that func you isolate the "connect" event and also look for an error code. When this happens, then you have a "connect error".

EDIT: I just pushed a small example update. You can see the pertinent part here:

Code: Select all

cb(sock, event, err) {

; Line: 186

    else if (sock.name = "client-err") { ; you don't have to "catch" the socket name, but I happened to do that here
        if (event = "connect") && err    ; <-- this is how you catch an error with async / non-blocking
            msgbox sock.name ": " event ": err: " err 
    }
}
antenne
Posts: 7
Joined: 18 Jan 2023, 07:48

Re: Socket Class - 2022/09/07 - beta.8

18 Jan 2023, 07:58

Hi @TheArkive,

is it possible to send a string via UDP? Can you please give me a small example?

Thank you very much :)
User avatar
TheArkive
Posts: 1027
Joined: 05 Aug 2016, 08:06
Location: The Construct
Contact:

Re: Socket Class - 2022/09/07 - beta.8

18 Jan 2023, 10:43

@antenne

Sadly the best example of that is already on the repo. I decided to focus on using the non-blocking method which is much more complex, but also much more versatile.

If you use the blocking mode, then it does get a little easier.

Check out F7 in the example, using test_google_blocking() function. That is about as easy as it gets, using TCP.

I still need to make an example using UDP.
antenne
Posts: 7
Joined: 18 Jan 2023, 07:48

Re: Socket Class - 2022/09/07 - beta.8

19 Jan 2023, 02:40

@TheArkive

Thanks for your quick answer.
Unfortunately I'm not getting it worked out.

Maybe you can make a quick example to just send a String via UDP to localhost on a specified Port?

Thanks!
User avatar
TheArkive
Posts: 1027
Joined: 05 Aug 2016, 08:06
Location: The Construct
Contact:

Re: Socket Class - 2022/09/07 - beta.8

19 Jan 2023, 03:32

@antenne

Are you looking for a blocking implementation, or ASYNC?

Return to “Scripts and Functions (v2)”

Who is online

Users browsing this forum: someguyinKC and 26 guests