Thinkai's Blog

Autohotkey|Python|php|aardio|VOIP|IT 爱好者

Socket套接字后台服务器和客户端 Autohotkey 7714

作者为 发表

Autohotkey


因工作需要使用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



来了就留个评论吧! 4个评论




友情链接:Autohotkey中文帮助Autohotkey官网Autohotkey中文网联系作者免GooglePlay APK下载

 主题设计 • skyfrit.com  Thinkai's Blog | 保留所有权利

62 queries in 3.259 seconds |