-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTCPServer.au3
More file actions
265 lines (234 loc) · 8.92 KB
/
Copy pathTCPServer.au3
File metadata and controls
265 lines (234 loc) · 8.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
#include-once
#cs
TCPServer UDF
Written by Jefrey <jefrey[at]jefrey.ml>
#ce
TCPStartup()
OnAutoItExitRegister("__TCPServer_OnExit")
Global $_TCPServer_OnConnectCallback, $_TCPServer_OnDisconnectCallback, $_TCPServer_OnReceiveCallback
Global $_TCPServer_MaxClients = 255
Global $_TCPServer_DebugMode = False
Global $_TCPServer_AutoTrim = True
Global $__TCPServer_MainSocket = -1
Global $__TCPServer_Sockets[255], $__TCPServer_SocketCache[255]
Global $__TCPServer_Consoles[255], $__TCPServer_Pars[255]
_TCPServer_SetMaxClients(255) ; default
Func _TCPServer_Start($iPort, $sInterface = '0.0.0.0')
If _TCPServer_IsServerActive() Then Return SetError(2, 0, False)
$__TCPServer_MainSocket = TCPListen($sInterface, $iPort)
If @error Then Return SetError(@error, @extended, False)
If $_TCPServer_DebugMode Then __TCPServer_Log("Started listening at " & $sInterface & ":" & $iPort)
AdlibRegister("__TCPServer_Accept")
AdlibRegister("__TCPServer_Recv")
AdlibRegister("__TCPServer_Sendstd")
EndFunc ;==>_TCPServer_Start
Func _TCPServer_Stop()
If Not _TCPServer_IsServerActive() Then Return
AdlibUnRegister("__TCPServer_Accept")
AdlibUnRegister("__TCPServer_Recv")
AdlibUnRegister("__TCPServer_Sendstd")
For $i = 1 To $_TCPServer_MaxClients
If $__TCPServer_Sockets[$i] <> 0 Then
TCPCloseSocket($__TCPServer_Sockets[$i])
$__TCPServer_Sockets[$i] = 0
$__TCPServer_SocketCache[$i][0] = 0
$__TCPServer_SocketCache[$i][1] = 0
$__TCPServer_Consoles[$i] = 0
$__TCPServer_Pars[$i] = 0
EndIf
Next
If $_TCPServer_DebugMode Then __TCPServer_Log("Stopping server")
TCPCloseSocket($__TCPServer_MainSocket)
$__TCPServer_MainSocket = -1
EndFunc ;==>_TCPServer_Stop
Func _TCPServer_IsServerActive()
Return $__TCPServer_MainSocket <> -1
EndFunc ;==>_TCPServer_IsServerActive
Func _TCPServer_ListClients()
;Dim $return[$__TCPServer_Sockets[0] + 1]
Dim $return[$_TCPServer_MaxClients + 1]
$return[0] = $__TCPServer_Sockets[0]
For $i = 1 To $_TCPServer_MaxClients
If $__TCPServer_Sockets[$i] <> 0 Then
$return[$i] = $__TCPServer_Sockets[$i]
EndIf
; falta testar
Next
Return $return
EndFunc ;==>_TCPServer_ListClients
Func _TCPServer_Close($iSocket)
$conn = _TCPServer_SocketToConnID($iSocket)
__TCPServer_KillConnection($conn)
EndFunc ;==>_TCPServer_Close
Func _TCPServer_OnConnect($sFunction)
$_TCPServer_OnConnectCallback = $sFunction
EndFunc ;==>_TCPServer_OnConnect
Func _TCPServer_SetMaxClients($iMax)
$_TCPServer_MaxClients = $iMax
ReDim $__TCPServer_Sockets[$iMax + 1]
ReDim $__TCPServer_SocketCache[$iMax + 1][2]
ReDim $__TCPServer_Consoles[$iMax + 1]
ReDim $__TCPServer_Pars[$iMax + 1]
For $i = 0 To $iMax
$__TCPServer_Sockets[$i] = 0
$__TCPServer_SocketCache[$i][0] = 0
$__TCPServer_SocketCache[$i][1] = 0
$__TCPServer_Consoles[$i] = 0
$__TCPServer_Pars[$i] = 0
Next
$__TCPServer_Sockets[0] = 0
EndFunc ;==>_TCPServer_SetMaxClients
Func _TCPServer_GetMaxClients()
Return $_TCPServer_MaxClients
EndFunc ;==>_TCPServer_GetMaxClients
Func _TCPServer_DebugMode($bMode = True)
$_TCPServer_DebugMode = $bMode
EndFunc ;==>_TCPServer_DebugMode
Func _TCPServer_AutoTrim($bMode = True)
$_TCPServer_AutoTrim = $bMode
EndFunc ;==>_TCPServer_AutoTrim
Func _TCPServer_OnDisconnect($sFunction)
$_TCPServer_OnDisconnectCallback = $sFunction
EndFunc ;==>_TCPServer_OnDisconnect
Func _TCPServer_OnReceive($sFunction)
$_TCPServer_OnReceiveCallback = $sFunction
EndFunc ;==>_TCPServer_OnReceive
Func _TCPServer_Broadcast($sData, $iExceptSocket = 0)
If $iExceptSocket Then $iExceptSocket = _TCPServer_SocketToConnID($iExceptSocket)
For $i = 1 To $__TCPServer_Sockets[0]
If $__TCPServer_Sockets[$i] <> 0 And $i <> $iExceptSocket Then
TCPSend($__TCPServer_Sockets[$i], $sData)
If $_TCPServer_DebugMode Then __TCPServer_Log("Sent " & StringLeft($sData, 255) & " to socket " & $__TCPServer_Sockets[$i] & "(" & _TCPServer_SocketToIP($__TCPServer_Sockets[$i]) & ")")
EndIf
Next
EndFunc ;==>_TCPServer_Broadcast
Func _TCPServer_Send($iSocket, $sData)
If $_TCPServer_DebugMode Then __TCPServer_Log("Sent " & $sData & " to socket " & $iSocket & "(" & _TCPServer_SocketToIP($iSocket) & ")")
Return TCPSend($iSocket, $sData)
EndFunc ;==>_TCPServer_Send
Func _TCPServer_SetParam($iSocket, $sPar)
$conn = _TCPServer_SocketToConnID($iSocket)
$__TCPServer_Pars[$conn] = $sPar
EndFunc ;==>_TCPServer_SetParam
Func _TCPServer_SocketToIP($iSocket) ; taken from the helpfile
Local $sockaddr, $aRet
$sockaddr = DllStructCreate("short;ushort;uint;char[8]")
$aRet = DllCall("Ws2_32.dll", "int", "getpeername", "int", $iSocket, _
"ptr", DllStructGetPtr($sockaddr), "int*", DllStructGetSize($sockaddr))
If Not @error And $aRet[0] = 0 Then
$aRet = DllCall("Ws2_32.dll", "str", "inet_ntoa", "int", DllStructGetData($sockaddr, 3))
If Not @error Then $aRet = $aRet[0]
Else
$aRet = 0
EndIf
$sockaddr = 0
Return $aRet
EndFunc ;==>_TCPServer_SocketToIP
Func _TCPServer_BindAppToSocket($iSocket, $sCommand, $sWorkingdir = @WorkingDir)
$PID = Run($sCommand, $sWorkingdir, @SW_HIDE, BitOR(0x1, 0x2, 0x4)) ; $STDIN_CHILD + STDOUT_CHILD + STDERR_CHILD
$conn = _TCPServer_SocketToConnID($iSocket)
$__TCPServer_Consoles[$conn] = $PID
If $_TCPServer_DebugMode Then __TCPServer_Log("Opened process " & $PID & " for socket " & $iSocket)
EndFunc ;==>_TCPServer_BindAppToSocket
Func _TCPServer_SendToBound($iSocket, $sData)
$conn = _TCPServer_SocketToConnID($iSocket)
$PID = $__TCPServer_Consoles[$conn]
StdinWrite($PID, $sData & @CRLF)
If $_TCPServer_DebugMode Then __TCPServer_Log("Sent command " & $sData & " to process " & $PID & " for socket " & $iSocket)
EndFunc ;==>_TCPServer_SendToBound
Func _TCPServer_UnBindAppToSocket($iSocket)
$iSocket = _TCPServer_SocketToConnID($iSocket)
$PID = $__TCPServer_Consoles[$iSocket]
$__TCPServer_Consoles[$iSocket] = 0
Sleep(300)
ProcessClose($PID)
EndFunc ;==>_TCPServer_UnBindAppToSocket
Func _TCPServer_SocketToConnID($iSocket)
For $i = 1 To $_TCPServer_MaxClients
If $__TCPServer_Sockets[$i] = $iSocket Then
Return $i
EndIf
Next
Return False
EndFunc ;==>_TCPServer_SocketToConnID
Func _TCPServer_ConnIDToSocket($iConn)
Return $__TCPServer_Sockets[$iConn]
EndFunc ;==>_TCPServer_ConnIDToSocket
; Internal use ============================================================
Func __TCPServer_OnExit()
TCPShutdown()
EndFunc ;==>__TCPServer_OnExit
Func __TCPServer_Sendstd()
For $i = 1 To $_TCPServer_MaxClients
If $__TCPServer_Consoles[$i] <> 0 Then
$PID = $__TCPServer_Consoles[$i]
$line = StdoutRead($PID)
If $line <> "" Then
TCPSend($__TCPServer_Sockets[$i], $line)
EndIf
EndIf
Next
EndFunc ;==>__TCPServer_Sendstd
Func __TCPServer_Accept()
If $__TCPServer_Sockets[0] >= $_TCPServer_MaxClients Then
Return
EndIf
$accept = TCPAccept($__TCPServer_MainSocket)
If $accept = -1 Then Return
For $i = 1 To $_TCPServer_MaxClients
If $__TCPServer_Sockets[$i] = 0 Then ; socket is empty
$__TCPServer_Sockets[$i] = $accept
$__TCPServer_Sockets[0] += 1
$__TCPServer_SocketCache[$i][0] = $accept
$__TCPServer_SocketCache[$i][1] = _TCPServer_SocketToIP($accept)
If $_TCPServer_DebugMode Then __TCPServer_Log("Client " & _TCPServer_SocketToIP($accept) & " connected to socket " & $accept)
Call($_TCPServer_OnConnectCallback, $__TCPServer_Sockets[$i], _TCPServer_SocketToIP($__TCPServer_Sockets[$i]))
Return 0
EndIf
Next
EndFunc ;==>__TCPServer_Accept
Func __TCPServer_KillConnection($iConn)
$iSocket = _TCPServer_ConnIDToSocket($iConn)
If $_TCPServer_DebugMode Then __TCPServer_Log("Closing socket " & $iSocket)
TCPCloseSocket($iSocket)
$__TCPServer_Sockets[$iConn] = 0
$__TCPServer_Sockets[0] -= 1
Call($_TCPServer_OnDisconnectCallback, $__TCPServer_SocketCache[$iConn][0], $__TCPServer_SocketCache[$iConn][1])
$__TCPServer_SocketCache[$iConn][0] = 0
$__TCPServer_SocketCache[$iConn][1] = 0
If $__TCPServer_Consoles[$iConn] <> 0 Then
ProcessClose($__TCPServer_Consoles[$iConn])
EndIf
$__TCPServer_Consoles[$iConn] = 0
$__TCPServer_Pars[$iConn] = 0
EndFunc ;==>__TCPServer_KillConnection
Func __TCPServer_Recv()
For $i = 1 To $_TCPServer_MaxClients
Dim $sData
If Not $__TCPServer_Sockets[$i] Then ContinueLoop
$recv = TCPRecv($__TCPServer_Sockets[$i], 1000000)
If @error Then
__TCPServer_KillConnection($i)
ContinueLoop
EndIf
If $recv Then
$sData = $recv
Do
$recv = TCPRecv($__TCPServer_Sockets[$i], 1000000)
If @error Then
__TCPServer_KillConnection($i)
ContinueLoop (2)
EndIf
$sData &= $recv
Until $recv = ""
If $_TCPServer_AutoTrim Then
$sData = StringStripWS($sData, 1 + 2)
EndIf
If $_TCPServer_DebugMode Then __TCPServer_Log("Client " & _TCPServer_SocketToIP($__TCPServer_Sockets[$i]) & " sent " & StringLeft($sData, 255))
Call($_TCPServer_OnReceiveCallback, $__TCPServer_Sockets[$i], _TCPServer_SocketToIP($__TCPServer_Sockets[$i]), $sData, $__TCPServer_Pars[$i])
EndIf
Next
EndFunc ;==>__TCPServer_Recv
Func __TCPServer_Log($sMsg)
ConsoleWrite(@CRLF & @MIN & ":" & @SEC & " > " & $sMsg)
EndFunc ;==>__TCPServer_Log