just me wrote:Why are you trying to cut down the scripts although you obviously do not understand how they work?
Isn't that obvious? Because the initial script contains lots of stuff I don't need (that script is a whole UDP lan chat) and I didn't know how to do what I needed other than cutting that script's functionality down to the minimum I need.
I'm sorry, but I'm not able to do that myself: it's not that I'm lazy or that I didn't try to understand how to do that, it's just they seem completely different to me: NumPut() is just a function with 4 parameters, while InsertInteger() [which generally has the same parameters (except for the last one that doesn't match NumPut()'s one)] inside of itself runs a loop of DllCall()s, while NumPut() does nothing of that at all.
just me wrote:- DllCall("Ws2_32\socket", "Int", 2, "Int", 2, "Int", 17) (http://msdn.microsoft.com/en-us/library ... s.85).aspx
will create a socket for
- AF_INET (2) -> IPv4
- SOCK_DGRAM (2)
- IPPROTO_UDP (17)
The function returns a SOCKET descriptor of type UINT_PTR which must be stored in a variable for further use.
Wow, that actually explained quite something for me (at least now I know the possible arguments for that DllCall. Seems like I've used the right arguments.
I wanted to ask what is UINT_PTR, but
this link seems to have explained what's that.
Got it, but I have another question here: I don't see how that function's syntax in C++
int bind(
_In_ SOCKET s,
_In_ const struct sockaddr *name,
_In_ int namelen
);
transformed into AHK's syntax
DllCall("Ws2_32\bind", "UInt", 284, "UInt", &SocketAddress, "Int", 16), because in C++ I see only 1 "int" for the third parameter, while that's not anyhow obvious that the first two parameters are UInts. Could you explain that?
Got it.
just me wrote:- The second parameter is FIONREAD (0x4004667f)
MSDN wrote:Use to determine the amount of data pending in the network's input buffer that can be read from socket s. The argp parameter points to an unsigned long value in which ioctlsocket stores the result. FIONREAD returns the amount of data that can be read in a single call to the recv function, which may not be the same as the total amount of data queued on the socket. If s is message oriented (for example, type SOCK_DGRAM), FIONREAD still returns the amount of pending data in the network buffer, however, the amount that can actually be read in a single call to the recv function is limited to the data size written in the send or sendto function call.
Sorry, but I don't understand what you meant by quoting: did you quote it just to give some explanation of what those 2nd and 3rd parameters in Ws2_32\ioctlsocket() mean or did you mean that I need to change the way they are used in my code?
Like this?
VarSetCapacity(packetContents, NumGet(U))
U := DllCall("Ws2_32\recv", "UInt", socket_S, "UInt", &packetContents, "UInt", NumGet(U))
Shall I execute this every time I run the check "are there any incoming packets to that port?" and thus put it into the loop I have?
You didn't say a single word about the code's structure (the sequence of commands and the correctness of the choice about what commands to run in a loop), does it need any changes?
just me wrote:BTW: You can find an updated version of Bentschi's Socket Class
here.
I don't know what's this. The code has no comments, and I'm still a total newb to all these DllCall()'s and VarSetCapacity()'s, so I'd better stick to my current task.
The result is the following, and now receiving a packet doesn't trigger anything at all.
Code: Select all
#SingleInstance, Force
OnExit, ExitSub
global U, global port, global socket_S, global packetContents
; Settings.
checkPeriod := 1000
port := 9 ; Port to monitor.
; Some initial voodoo magic.
VarSetCapacity(wsaData, 32)
VarSetCapacity(SocketAddress, 16)
VarSetCapacity(U, 1024)
DllCall("Ws2_32\WSAStartup", "UShort", 0x0002, "UInt", &wsaData)
socket_S := DllCall("Ws2_32\socket", "Int", 2, "Int", 2, "Int", 17)
InsertInteger(2, SocketAddress, 0, 2)
InsertInteger(DllCall("Ws2_32\htons", "UShort", Port), SocketAddress, 2, 2)
InsertInteger(DllCall("Ws2_32\inet_addr", "Str", 0), SocketAddress, 4, 4)
DllCall("Ws2_32\bind", "UInt", socket_S, "UInt", &SocketAddress, "Int", 16)
Loop ; Periodic check.
{
VarSetCapacity(packetContents, NumGet(U))
U := DllCall("Ws2_32\recv", "UInt", socket_S, "UInt", &packetContents, "UInt", NumGet(U))
DllCall("Ws2_32\ioctlsocket", "UInt", socket_S, "UInt", 0x4004667f, "UInt", &U)
If NumGet(U) != 0
trigger()
Sleep, checkPeriod
}
InsertInteger(pInteger, ByRef pDest, pOffset = 0, pSize = 4) ; Voodoo magic.
{
Loop %pSize%
DllCall("RtlFillMemory", "UInt", &pDest + pOffset + A_Index-1, "UInt", 1, "UChar", pInteger >> 8*(A_Index-1) & 0xFF)
}
trigger() ; We got a packet.
{
msgbox U: '%U%'`nsocket_S: '%socket_S%'`npacketContents: '%packetContents%'`n
}
ExitSub: ; Clean something upon exit.
DllCall("Ws2_32\WSACleanup")
ExitApp
just me, thanks a lot for your help, but I'm going to need some more
question := (2b) || !(2b) © Shakespeare.