因工作需要使用Asterisk AMI接口,是套接字连接方式的,用php单线程不好用,所以找了一下资料,改动下成后台静默模式,当然你也可以自己改有界面的。
服务器Server:
;thinkai@2014-11-08 ;Based on http://www.autohotkey.com/board/topic/29650-tcpip-serverclient-chat-script-w-features #singleinstance force OnExit, exit ;创建窗口以接收数据 Gui, add, Edit gui, hide ;ip和端口 Network_Address = 0.0.0.0 Network_Port = 1000 ;准备传入连接 socket := PrepareForIncomingConnection(Network_Address, Network_Port) if socket = -1 ExitApp Process, Exist ;获取窗口句柄 DetectHiddenWindows On ScriptMainWindowId := WinExist("ahk_class AutoHotkey ahk_pid " . ErrorLevel) DetectHiddenWindows Off NotificationMsg = 0x5555 ;设置接收消息的函数 OnMessage(NotificationMsg, "ReceiveData") FD_READ = 1 FD_CLOSE = 32 FD_CONNECT = 20 if DllCall("Ws2_32\WSAAsyncSelect", "UInt", socket, "UInt", ScriptMainWindowId, "UInt", NotificationMsg, "Int", FD_READ|FD_CONNECT) { MsgBox % "WSAAsyncSelect() indicated Winsock error " . DllCall("Ws2_32\WSAGetLastError") ExitApp } ;循环获取新连入客户端 i=1 Loop { VarSetCapacity(SocketAddress, SizeOfSocketAddress:=16) ;Socket连接 conectioncheck%i% := DllCall("Ws2_32\accept", "UInt", socket, "UInt", &SocketAddress, "Int*", SizeOfSocketAddress) if conectioncheck%i% != -1 { ;该客户端连接对象为conectioncheck%i% 发送数据时需要 ;客户端IP:端口 xxx.xxx.xxx.xxx:xxxx peername := DllCall("Ws2_32\inet_ntoa", "uint", NumGet(SocketAddress,4), "str") . ":" NumGet(SocketAddress,2,"ushort") ;发送欢迎信息 SendData(conectioncheck%i%,"欢迎" peername) i++ } sleep 500 } return ;给所有客户端发消息 sendall: Loop %i% { SendData(conectioncheck%A_Index%,SendText) } SendText= return ;准备传入连接函数 PrepareForIncomingConnection(IPAddress, Port) { VarSetCapacity(wsaData, 32) result := DllCall("Ws2_32\WSAStartup", "UShort", 0x0002, "UInt", &wsaData) ; Request Winsock 2.0 (0x0002) if ErrorLevel { MsgBox WSAStartup() could not be called due to error %ErrorLevel%. Winsock 2.0 or higher is required. return -1 } if result { MsgBox % "WSAStartup() indicated Winsock error " . DllCall("Ws2_32\WSAGetLastError") return -1 } AF_INET = 2 SOCK_STREAM = 1 IPPROTO_TCP = 6 socket := DllCall("Ws2_32\socket", "Int", AF_INET, "Int", SOCK_STREAM, "Int", IPPROTO_TCP) if socket = -1 { MsgBox % "socket() indicated Winsock error " . DllCall("Ws2_32\WSAGetLastError") return -1 } SizeOfSocketAddress = 16 VarSetCapacity(SocketAddress, SizeOfSocketAddress) InsertInteger(2, SocketAddress, 0, AF_INET) ; sin_family InsertInteger(DllCall("Ws2_32\htons", "UShort", Port), SocketAddress, 2, 2) ; sin_port InsertInteger(DllCall("Ws2_32\inet_addr", "Str", IPAddress), SocketAddress, 4, 4) ; sin_addr.s_addr if DllCall("Ws2_32\bind", "UInt", socket, "UInt", &SocketAddress, "Int", SizeOfSocketAddress) { MsgBox % "bind() indicated Winsock error " . DllCall("Ws2_32\WSAGetLastError") . "?" return -1 } if DllCall("Ws2_32\listen", "UInt", socket, "UInt", "SOMAXCONN") { MsgBox % "LISTEN() indicated Winsock error " . DllCall("Ws2_32\WSAGetLastError") . "?" return -1 } return socket } ;接收消息函数 ReceiveData(wParam, lParam) { Critical global ShowRecieved socket := wParam ReceivedDataSize = 4096 Loop { VarSetCapacity(ReceivedData, ReceivedDataSize, 0) ReceivedDataLength := DllCall("Ws2_32\recv", "UInt", socket, "Str", ReceivedData, "Int", ReceivedDataSize, "Int", 0) if ReceivedDataLength = -1 { WinsockError := DllCall("Ws2_32\WSAGetLastError") if WinsockError = 10035 return 1 if WinsockError <> 10054 MsgBox % "recv() indicated Winsock error " . WinsockError ExitApp } ;addmsg(ReceivedData) ;此处已获取到消息 MsgBox % ReceivedData } return 1 } ;发送消息函数 SendData(wParam,SendData) { socket := wParam SendDataSize := VarSetCapacity(SendData) SendDataSize += 1 sendret := DllCall("Ws2_32\send", "UInt", socket, "Str", SendData, "Int", SendDatasize, "Int", 0) } InsertInteger(pInteger, ByRef pDest, pOffset = 0, pSize = 4) { Loop %pSize% DllCall("RtlFillMemory", "UInt", &pDest + pOffset + A_Index-1, "UInt", 1, "UChar", pInteger >> 8*(A_Index-1) & 0xFF) } CloseSocket(Socket) { Result := DllCall("Ws2_32\closesocket" , "UInt", Socket) Return result } exit: ;清除连接 Loop %i% { CloseSocket(conectioncheck%A_Index%) } DllCall("Ws2_32\WSACleanup") ExitApp
客户端Client:
;thinkai@2014-11-08 ;Based on http://www.autohotkey.com/board/topic/29650-tcpip-serverclient-chat-script-w-features #singleinstance force OnExit, exit ;创建窗口以接收数据 Gui, add, Edit Gui, hide ;客户端名称 服务器地址 端口 ClientName=%A_Computername% Network_Address = 135.230.71.250 Network_Port = 1000 ;连接到服务器 socket := ConnectToAddress(Network_Address, Network_Port) if socket = -1 ExitApp ;获取窗口句柄 Process, Exist DetectHiddenWindows On ScriptMainWindowId := WinExist("ahk_class AutoHotkey ahk_pid " . ErrorLevel) DetectHiddenWindows Off ;获取窗口句柄 NotificationMsg = 0x5555 ; An arbitrary message number, but should be greater than 0x1000. OnMessage(NotificationMsg, "ReceiveData") FD_READ = 1 ; Received when data is available to be read. FD_CLOSE = 32 ; Received when connection has been closed. if DllCall("Ws2_32\WSAAsyncSelect", "UInt", socket, "UInt", ScriptMainWindowId, "UInt", NotificationMsg, "Int", FD_READ|FD_CLOSE) { MsgBox % "WSAAsyncSelect() indicated Winsock error " . DllCall("Ws2_32\WSAGetLastError") ExitApp } ;发送连接好消息 SendData(socket,ClientName " Login!") return ;发送消息 send: SendData(socket,SendText) SendText = return ;连接服务器函数 ConnectToAddress(IPAddress, Port) { VarSetCapacity(wsaData, 32) result := DllCall("Ws2_32\WSAStartup", "UShort", 0x0002, "UInt", &wsaData) if ErrorLevel { MsgBox WSAStartup() could not be called due to error %ErrorLevel%. Winsock 2.0 or higher is required. return -1 } if result { MsgBox % "WSAStartup() indicated Winsock error " . DllCall("Ws2_32\WSAGetLastError") return -1 } AF_INET = 2 SOCK_STREAM = 1 IPPROTO_TCP = 6 socket := DllCall("Ws2_32\socket", "Int", AF_INET, "Int", SOCK_STREAM, "Int", IPPROTO_TCP) if socket = -1 { MsgBox % "socket() indicated Winsock error " . DllCall("Ws2_32\WSAGetLastError") return -1 } SizeOfSocketAddress = 16 VarSetCapacity(SocketAddress, SizeOfSocketAddress) InsertInteger(2, SocketAddress, 0, AF_INET) InsertInteger(DllCall("Ws2_32\htons", "UShort", Port), SocketAddress, 2, 2) InsertInteger(DllCall("Ws2_32\inet_addr", "Str", IPAddress), SocketAddress, 4, 4) if DllCall("Ws2_32\connect", "UInt", socket, "UInt", &SocketAddress, "Int", SizeOfSocketAddress) { MsgBox % "connect() indicated Winsock error " . DllCall("Ws2_32\WSAGetLastError") . "?" return -1 } return socket } ;接收函数 ReceiveData(wParam, lParam) { Critical global ShowRecieved socket := wParam ReceivedDataSize = 4096 Loop { VarSetCapacity(ReceivedData, ReceivedDataSize, 0) ReceivedDataLength := DllCall("Ws2_32\recv", "UInt", socket, "Str", ReceivedData, "Int", ReceivedDataSize, "Int", 0) if ReceivedDataLength = 0 ExitApp if ReceivedDataLength = -1 { WinsockError := DllCall("Ws2_32\WSAGetLastError") if WinsockError = 10035 return 1 if WinsockError <> 10054 MsgBox % "recv() indicated Winsock error " . WinsockError ExitApp } ;ReceivedData } return 1 } ;发送函数 SendData(wParam,SendData) { socket := wParam SendDataSize := VarSetCapacity(SendData) SendDataSize += 1 sendret := DllCall("Ws2_32\send", "UInt", socket, "Str", SendData, "Int", SendDatasize, "Int", 0) } InsertInteger(pInteger, ByRef pDest, pOffset = 0, pSize = 4) { Loop %pSize% DllCall("RtlFillMemory", "UInt", &pDest + pOffset + A_Index-1, "UInt", 1, "UChar", pInteger >> 8*(A_Index-1) & 0xFF) } CloseSocket(Socket) { Result := DllCall("Ws2_32\closesocket" , "UInt", Socket) Return result } GuiClose: exit: ;清除连接 CloseSocket(socket) DllCall("Ws2_32\WSACleanup") ExitApp
62 queries in 3.259 seconds |