<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title><![CDATA[Серый форум &mdash; AHK: TCP сервер. Посылать клиенту когда хочет, а не только в ответ]]></title>
		<link>https://forum.script-coding.com/viewtopic.php?id=12363</link>
		<atom:link href="https://forum.script-coding.com/extern.php?action=feed&amp;tid=12363&amp;type=rss" rel="self" type="application/rss+xml" />
		<description><![CDATA[Недавние сообщения в теме «AHK: TCP сервер. Посылать клиенту когда хочет, а не только в ответ».]]></description>
		<lastBuildDate>Wed, 25 Jan 2017 17:39:00 +0000</lastBuildDate>
		<generator>PunBB</generator>
		<item>
			<title><![CDATA[Re: AHK: TCP сервер. Посылать клиенту когда хочет, а не только в ответ]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=111547#p111547</link>
			<description><![CDATA[<p>Вообщем нашел в интернете echoserver просто добавил кнопку и все работает.<br /></p><div class="codebox"><pre><code>#SingleInstance Force
Network_Port = 27015
Network_Address = 192.168.0.102
 
NewData := false
DataReceived =
Gosub Connection_Init
return
 
Connection_Init:
OnExit, ExitSub
socket := PrepareForIncomingConnection(Network_Address, Network_Port)
if socket = -1
    ExitApp
 
Process, Exist
DetectHiddenWindows On
ScriptMainWindowId := WinExist(&quot;ahk_class AutoHotkey ahk_pid &quot; . ErrorLevel)
DetectHiddenWindows Off
 
NotificationMsg = 0x5555
OnMessage(NotificationMsg, &quot;ReceiveData&quot;)
 
ExitMsg = 0x6666
OnMessage(ExitMsg, &quot;ExitData&quot;)
 
FD_READ = 1
FD_CLOSE = 32
FD_CONNECT = 20
 
if DllCall(&quot;Ws2_32\WSAAsyncSelect&quot;, &quot;UInt&quot;, socket, &quot;UInt&quot;, ScriptMainWindowId, &quot;UInt&quot;, ExitMsg, &quot;Int&quot;, FD_CLOSE)
{
    msgbox, closed
}
 
if DllCall(&quot;Ws2_32\WSAAsyncSelect&quot;, &quot;UInt&quot;, socket, &quot;UInt&quot;, ScriptMainWindowId, &quot;UInt&quot;, NotificationMsg, 

&quot;Int&quot;,FD_READ|FD_CONNECT) 
{
    MsgBox % &quot;WSAAsyncSelect() indicated Winsock error &quot;
          . DllCall(&quot;Ws2_32\WSAGetLastError&quot;)
    DllCall(&quot;Ws2_32\WSAAsyncSelect&quot;, &quot;UInt&quot;, socket, &quot;UInt&quot;, ScriptMainWindowId, &quot;UInt&quot;, ExitMsg, &quot;Int&quot;, 

FD_CLOSE)
    ExitApp
}
;msgbox, NotificationMsg = %NotificationMsg%
SetTimer, NewConnectionCheck, 500
return
 
PrepareForIncomingConnection(IPAddress, Port)
{
    VarSetCapacity(wsaData, 32)
    result := DllCall(&quot;Ws2_32\WSAStartup&quot;, &quot;UShort&quot;, 0x0002, &quot;UInt&quot;, &amp;wsaData)
    if ErrorLevel
    {
        MsgBox % &quot;WSAStartup() could not be called due to error %ErrorLevel%. &quot;
                . &quot;Winsock 2.0 or higher is required.&quot;
        return -1
    }
    if result
    {
        MsgBox % &quot;WSAStartup() indicated Winsock error &quot;
                . DllCall(&quot;Ws2_32\WSAGetLastError&quot;)
        return -1
    }
    AF_INET = 2
    SOCK_STREAM = 1
    IPPROTO_TCP = 6
    socket := DllCall(&quot;Ws2_32\socket&quot;, &quot;Int&quot;, AF_INET, &quot;Int&quot;, SOCK_STREAM, &quot;Int&quot;, IPPROTO_TCP)
    if socket = -1
    {
        MsgBox % &quot;socket() indicated Winsock error &quot;
                . DllCall(&quot;Ws2_32\WSAGetLastError&quot;)
        return -1
    }
    SizeOfSocketAddress = 16
    VarSetCapacity(SocketAddress, SizeOfSocketAddress)
    InsertInteger(2, SocketAddress, 0, AF_INET)
    InsertInteger(DllCall(&quot;Ws2_32\htons&quot;, &quot;UShort&quot;, Port), SocketAddress, 2, 2)
    InsertInteger(DllCall(&quot;Ws2_32\inet_addr&quot;, &quot;Str&quot;, IPAddress),SocketAddress, 4, 4)
    if DllCall(&quot;Ws2_32\bind&quot;, &quot;UInt&quot;, socket, &quot;UInt&quot;, &amp;SocketAddress, &quot;Int&quot;, SizeOfSocketAddress)
    {
        MsgBox % &quot;bind() indicated Winsock error &quot;
                . DllCall(&quot;Ws2_32\WSAGetLastError&quot;) . &quot;?&quot;
        return -1
    }
    if DllCall(&quot;Ws2_32\listen&quot;, &quot;UInt&quot;, socket, &quot;UInt&quot;, &quot;SOMAXCONN&quot;)
    {
        MsgBox % &quot;LISTEN() indicated Winsock error &quot;
                . DllCall(&quot;Ws2_32\WSAGetLastError&quot;) . &quot;?&quot;
        return -1
    }
    return socket
}
 
ReceiveData(wParam, lParam)
{
    global DataReceived
    global NewData
    global mydata
    global ConnectionList
    socket := wParam
    ReceivedDataSize = 4096
    Loop
    {
        VarSetCapacity(ReceivedData, ReceivedDataSize, 0)
        ReceivedDataLength := DllCall(&quot;Ws2_32\recv&quot;, &quot;UInt&quot;, socket, &quot;Str&quot;, ReceivedData, &quot;Int&quot;, 

ReceivedDataSize, &quot;Int&quot;, 0)
	if ReceivedDataLength = 0
        {   
            StringReplace, ConnectionList, ConnectionList, %socket%`n
            DllCall(&quot;Ws2_32\closesocket&quot;, &quot;UInt&quot;, socket)
        } 
        if ReceivedDataLength = -1
        {
            WinsockError := DllCall(&quot;Ws2_32\WSAGetLastError&quot;)
            if WinsockError = 10035
            {
                DataReceived = %TempDataReceived%
                NewData := true
                return 1
            }
            if WinsockError &lt;&gt; 10054
            {
                MsgBox % &quot;recv() indicated Winsock error &quot; . WinsockError
                StringReplace, ConnectionList, ConnectionList, %socket%`n
                DllCall(&quot;Ws2_32\closesocket&quot;, &quot;UInt&quot;, socket)
            }
        }
        mydata := ReceivedData
        gosub myreceive
	if (A_Index = 1)
            TempDataReceived =
                TempDataReceived = %TempDataReceived%%ReceivedData%
    }
    return 1
}
 
ExitData(wParam, lParam)
{
    global ConnectionList
    socket := wParam
    ReceivedDataSize = 16
    VarSetCapacity(ReceivedData, ReceivedDataSize, 0)
    ReceivedDataLength := DllCall(&quot;Ws2_32\recv&quot;, &quot;UInt&quot;, socket, &quot;Str&quot;, ReceivedData, &quot;Int&quot;, ReceivedDataSize, 

&quot;Int&quot;, 0)
    StringReplace, ConnectionList, ConnectionList, %socket%`n
    DllCall(&quot;Ws2_32\closesocket&quot;, &quot;UInt&quot;, socket)
    return 1
}
 
SendData(wParam,SendData)
{
    SendDataSize := VarSetCapacity(SendData)
    SendDataSize += 1
    Loop, parse, wParam, `n
    {
        If A_LoopField =
           Continue
        socket := A_LoopField
        sendret := DllCall(&quot;Ws2_32\send&quot;, &quot;UInt&quot;, socket, &quot;Str&quot;, SendData, &quot;Int&quot;, SendDatasize, &quot;Int&quot;, 0)
    }
}
 
 
InsertInteger(pInteger, ByRef pDest, pOffset = 0, pSize = 4)
{
    Loop %pSize%
        DllCall(&quot;RtlFillMemory&quot;, &quot;UInt&quot;, &amp;pDest + pOffset + A_Index-1, &quot;UInt&quot;, 1, &quot;UChar&quot;, pInteger &gt;&gt; 8*

(A_Index-1) &amp; 0xFF)
}
 
NewConnectionCheck:
ConnectionCheck := DllCall(&quot;Ws2_32\accept&quot;, &quot;UInt&quot;, socket, &quot;UInt&quot;, &amp;SocketAddress, &quot;Int&quot;, SizeOfSocketAddress)
if ConnectionCheck &gt; 1
    ConnectionList = %ConnectionList%%ConnectionCheck%`n
Return
 
myreceive:
msgbox, %mydata%
return
 
GuiClose:
ExitSub:
DllCall(&quot;Ws2_32\WSACleanup&quot;)
ExitApp

F2::
If ConnectionList &lt;&gt;
{
    SendText = test
    sendData(ConnectionList,SendText)
}
else
{
    msgbox, Нет клиентов
}
return</code></pre></div><p>кстати отсылает сразу нескольким клиентам.</p>]]></description>
			<author><![CDATA[null@example.com (Dworkin)]]></author>
			<pubDate>Wed, 25 Jan 2017 17:39:00 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=111547#p111547</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: TCP сервер. Посылать клиенту когда хочет, а не только в ответ]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=111539#p111539</link>
			<description><![CDATA[<p>Не могу понять почему это не работает...То есть клиент конектится к серверу, но сервер не отсылает клиенту текст.<br /></p><div class="codebox"><pre><code>#Include socket.ahk
 MyTcp := new SocketTCP()
 MyTcp.bind(&quot;127.0.0.1&quot;, 12345)
 MyTcp.listen()
 MyTcp.accept()
 MyTcp.sendText(&quot;Connected&quot;)</code></pre></div><p>Еще я нашел код от этого автора, но он не работает несмотря на что я подправил синтаксис.<br /></p><div class="codebox"><pre><code>myTcp := new SocketTCP()
myTcp.bind(&quot;addr_any&quot;, 12345)
myTcp.listen()
clients := []
myTcp.onAccept := Func(&quot;OnTCPAccept&quot;)
return

OnTCPAccept(){
global myTcp
clients.insert(myTcp.accept())
}

SendToAll(msg)
{
  global clients
  for k,v in clients
    v.send(msg)
}</code></pre></div><p>Насколько я понял что в функции accept() есть адресс клиента куда отсылать ответ тоесть мне надо его узнать. Далее в библиотеке в функции send есть адресс.<br /></p><div class="codebox"><pre><code>  send(addr, length)
  {
    if ((r := DllCall(&quot;ws2_32\send&quot;, &quot;ptr&quot;, this.socket, &quot;ptr&quot;, addr, &quot;int&quot;, length, &quot;int&quot;, 0, &quot;int&quot;))&lt;=0)
      return 0
    return r
  }

  sendText(msg, encoding=&quot;UTF-8&quot;)
  {
    VarSetCapacity(buffer, length := (StrPut(msg, encoding)*(((encoding=&quot;utf-16&quot;)||(encoding=&quot;cp1200&quot;)) ? 2 : 1)))
    StrPut(msg, &amp;buffer, encoding)
    return this.send(&amp;buffer, length)
  }</code></pre></div>]]></description>
			<author><![CDATA[null@example.com (Dworkin)]]></author>
			<pubDate>Wed, 25 Jan 2017 14:27:35 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=111539#p111539</guid>
		</item>
		<item>
			<title><![CDATA[AHK: TCP сервер. Посылать клиенту когда хочет, а не только в ответ]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=111535#p111535</link>
			<description><![CDATA[<p>Добрый день. Нашел тему на немецком TCP сервер и клиент, проблема в том что сервер отвечает(пишет) клиенту только когда клиент что-то посылает ему(текст). Я как ни крутил так и не получилось что бы сервер посылал клиенту текст когда хочет.</p><p>Сервер:<br /></p><div class="codebox"><pre><code>
;Server

#include Socket.ahk
;beep()
myTcp := new SocketTCP()
myTcp.bind(&quot;127.0.0.1&quot;, 12345)
myTcp.listen()
myTcp.onAccept := Func(&quot;OnTCPAccept&quot;)
return

OnTCPAccept(this)
{
    newTcp := this.accept()
    newTcp.onRecv := func(&quot;OnTCPRecv&quot;)
    newTcp.sendText(&quot;Connected&quot;)
}

OnTCPRecv(this)
{
    msgbox % this.recvText()
    this.recvText()
    this.sendText(&quot;Hello again&quot;)
}</code></pre></div><p>В качестве клиента я использую программу hercules<br /><a href="http://hercules-setup.soft32.com/free-download/">http://hercules-setup.soft32.com/free-download/</a><br />Или на андроид программу из playmarket &quot;easytcp&quot;</p><p>Вот библиотека:<br /></p><div class="codebox"><pre><code>class Socket
{
  static __eventMsg := 0x9987
  
  __New(s=-1)
  {
    static init
    if (!init)
    {
      DllCall(&quot;LoadLibrary&quot;, &quot;str&quot;, &quot;ws2_32&quot;, &quot;ptr&quot;)
      VarSetCapacity(wsadata, 394+A_PtrSize)
      DllCall(&quot;ws2_32\WSAStartup&quot;, &quot;ushort&quot;, 0x0000, &quot;ptr&quot;, &amp;wsadata)
      DllCall(&quot;ws2_32\WSAStartup&quot;, &quot;ushort&quot;, NumGet(wsadata, 2, &quot;ushort&quot;), &quot;ptr&quot;, &amp;wsadata)
      OnMessage(Socket.__eventMsg, &quot;SocketEventProc&quot;)
      init := 1
    }
    this.socket := s
  }
  __Delete()
  {
    this.disconnect()
  }
  __Get(k, v)
  {
    if (k=&quot;size&quot;)
      return this.msgSize()
  }
  connect(host, port)
  {
    if ((this.socket!=-1) || (!(faddr := next := this.__getAddrInfo(host, port))))
      return 0
    while (next)
    {
      sockaddrlen := NumGet(next+0, 16, &quot;uint&quot;)
      sockaddr := NumGet(next+0, 16+(2*A_PtrSize), &quot;ptr&quot;)
      if ((this.socket := DllCall(&quot;ws2_32\socket&quot;, &quot;int&quot;, NumGet(next+0, 4, &quot;int&quot;), &quot;int&quot;, this.__socketType, &quot;int&quot;, this.__protocolId, &quot;ptr&quot;))!=-1)
      {
        if ((r := DllCall(&quot;ws2_32\WSAConnect&quot;, &quot;ptr&quot;, this.socket, &quot;ptr&quot;, sockaddr, &quot;uint&quot;, sockaddrlen, &quot;ptr&quot;, 0, &quot;ptr&quot;, 0, &quot;ptr&quot;, 0, &quot;ptr&quot;, 0, &quot;int&quot;))=0)
        {
          DllCall(&quot;ws2_32\freeaddrinfo&quot;, &quot;ptr&quot;, faddr)
          return Socket.__eventProcRegister(this, 0x21)
        }
        this.disconnect()
      }
      next := NumGet(next+0, 16+(3*A_PtrSize), &quot;ptr&quot;)
    }
    this.lastError := DllCall(&quot;ws2_32\WSAGetLastError&quot;)
    return 0
  }
  bind(host, port)
  {
    if ((this.socket!=-1) || (!(faddr := next := this.__getAddrInfo(host, port))))
      return 0
    while (next)
    {
      sockaddrlen := NumGet(next+0, 16, &quot;uint&quot;)
      sockaddr := NumGet(next+0, 16+(2*A_PtrSize), &quot;ptr&quot;)
      if ((this.socket := DllCall(&quot;ws2_32\socket&quot;, &quot;int&quot;, NumGet(next+0, 4, &quot;int&quot;), &quot;int&quot;, this.__socketType, &quot;int&quot;, this.__protocolId, &quot;ptr&quot;))!=-1)
      {
        if (DllCall(&quot;ws2_32\bind&quot;, &quot;ptr&quot;, this.socket, &quot;ptr&quot;, sockaddr, &quot;uint&quot;, sockaddrlen, &quot;int&quot;)=0)
        {
          DllCall(&quot;ws2_32\freeaddrinfo&quot;, &quot;ptr&quot;, faddr)
          return Socket.__eventProcRegister(this, 0x29)
        }
        this.disconnect()
      }
      next := NumGet(next+0, 16+(3*A_PtrSize), &quot;ptr&quot;)
    }
    this.lastError := DllCall(&quot;ws2_32\WSAGetLastError&quot;)
    return 0
  }
  listen(backlog=32)
  {
    return (DllCall(&quot;ws2_32\listen&quot;, &quot;ptr&quot;, this.socket, &quot;int&quot;, backlog)=0) ? 1 : 0
  }
  accept()
  {
    if ((s := DllCall(&quot;ws2_32\accept&quot;, &quot;ptr&quot;, this.socket, &quot;ptr&quot;, 0, &quot;int&quot;, 0, &quot;ptr&quot;))!=-1)
    {
      newsock := new Socket(s)
      newsock.__protocolId := this.__protocolId
      newsock.__socketType := this.__socketType
      Socket.__eventProcRegister(newsock, 0x21)
      return newsock
    }
    return 0
  }
  disconnect()
  {
    Socket.__eventProcUnregister(this)
    DllCall(&quot;ws2_32\closesocket&quot;, &quot;ptr&quot;, this.socket, &quot;int&quot;)
    this.socket := -1
    return 1
  }
  msgSize()
  {
    VarSetCapacity(argp, 4, 0)
    if (DllCall(&quot;ws2_32\ioctlsocket&quot;, &quot;ptr&quot;, this.socket, &quot;uint&quot;, 0x4004667F, &quot;ptr&quot;, &amp;argp)!=0)
      return 0
    return NumGet(argp, 0, &quot;int&quot;)
  }
  send(addr, length)
  {
    if ((r := DllCall(&quot;ws2_32\send&quot;, &quot;ptr&quot;, this.socket, &quot;ptr&quot;, addr, &quot;int&quot;, length, &quot;int&quot;, 0, &quot;int&quot;))&lt;=0)
      return 0
    return r
  }
  sendText(msg, encoding=&quot;UTF-8&quot;)
  {
    VarSetCapacity(buffer, length := (StrPut(msg, encoding)*(((encoding=&quot;utf-16&quot;)||(encoding=&quot;cp1200&quot;)) ? 2 : 1)))
    StrPut(msg, &amp;buffer, encoding)
    return this.send(&amp;buffer, length)
  }
  recv(byref buffer, wait=1)
  {
    while ((wait) &amp;&amp; ((length := this.msgSize())=0))
      sleep, 100
    if (length)
    {
      VarSetCapacity(buffer, length)
      if ((r := DllCall(&quot;ws2_32\recv&quot;, &quot;ptr&quot;, this.socket, &quot;ptr&quot;, &amp;buffer, &quot;int&quot;, length, &quot;int&quot;, 0))&lt;=0)
        return 0
      return r
    }
    return 0
  }
  recvText(wait=1, encoding=&quot;UTF-8&quot;)
  {
    if (length := this.recv(buffer, wait))
      return StrGet(&amp;buffer, length, encoding)
    return
  }
  __getAddrInfo(host, port)
  {
    a := [&quot;127.0.0.1&quot;, &quot;0.0.0.0&quot;, &quot;255.255.255.255&quot;, &quot;::1&quot;, &quot;::&quot;, &quot;FF00::&quot;]
    conv := {localhost:a[1], addr_loopback:a[1], inaddr_loopback:a[1], addr_any:a[2], inaddr_any:a[2], addr_broadcast:a[3]
    , inaddr_broadcast:a[3], addr_none:a[3], inaddr_none:a[3], localhost6:a[4], addr_loopback6:a[4], inaddr_loopback6:a[4]
    , addr_any6:a[5], inaddr_any:a[5], addr_broadcast6:a[6], inaddr_broadcast6:a[6], addr_none6:a[6], inaddr_none6:a[6]}
    if (conv[host])
      host := conv[host]
    VarSetCapacity(hints, 16+(4*A_PtrSize), 0)
    NumPut(this.__socketType, hints, 8, &quot;int&quot;)
    NumPut(this.__protocolId, hints, 12, &quot;int&quot;)
    if ((r := DllCall(&quot;ws2_32\getaddrinfo&quot;, &quot;astr&quot;, host, &quot;astr&quot;, port, &quot;ptr&quot;, &amp;hints, &quot;ptr*&quot;, next))!=0)
    {
      this.lastError := DllCall(&quot;ws2_32\WSAGetLastError&quot;)
      return 0
    }
    return next
  }
  __eventProcRegister(obj, msg)
  {
    a := SocketEventProc(0, 0, &quot;register&quot;, 0)
    a[obj.socket] := obj
    return (DllCall(&quot;ws2_32\WSAAsyncSelect&quot;, &quot;ptr&quot;, obj.socket, &quot;ptr&quot;, A_ScriptHwnd, &quot;uint&quot;, Socket.__eventMsg, &quot;uint&quot;, msg)=0) ? 1 : 0
  }
  __eventProcUnregister(obj)
  {
    a := SocketEventProc(0, 0, &quot;register&quot;, 0)
    a.remove(obj.socket)
    return (DllCall(&quot;ws2_32\WSAAsyncSelect&quot;, &quot;ptr&quot;, obj.socket, &quot;ptr&quot;, A_ScriptHwnd, &quot;uint&quot;, 0, &quot;uint&quot;, 0)=0) ? 1 : 0
  }
}
SocketEventProc(wParam, lParam, msg, hwnd)
{
  global Socket
  static a := []
  Critical
  if (msg=&quot;register&quot;)
    return a
  if (msg=Socket.__eventMsg)
  {
    if (!isobject(a[wParam]))
      return 0
    if ((lParam &amp; 0xFFFF) = 1)
      return a[wParam].onRecv(a[wParam])
    else if ((lParam &amp; 0xFFFF) = 8)
      return a[wParam].onAccept(a[wParam])
    else if ((lParam &amp; 0xFFFF) = 32)
    {
      a[wParam].socket := -1
      return a[wParam].onDisconnect(a[wParam])
    }
    return 0
  }
  return 0
}

class SocketTCP extends Socket
{
  static __protocolId := 6 ;IPPROTO_TCP
  static __socketType := 1 ;SOCK_STREAM
}

class SocketUDP extends Socket
{
  static __protocolId := 17 ;IPPROTO_UDP
  static __socketType := 2 ;SOCK_DGRAM

  enableBroadcast()
  {
    VarSetCapacity(optval, 4, 0)
    NumPut(1, optval, 0, &quot;uint&quot;)
    if (DllCall(&quot;ws2_32\setsockopt&quot;, &quot;ptr&quot;, this.socket, &quot;int&quot;, 0xFFFF, &quot;int&quot;, 0x0020, &quot;ptr&quot;, &amp;optval, &quot;int&quot;, 4)=0)
      return 1
    return 0
  }
  disableBroadcast()
  {
    VarSetCapacity(optval, 4, 0)
    if (DllCall(&quot;ws2_32\setsockopt&quot;, &quot;ptr&quot;, this.socket, &quot;int&quot;, 0xFFFF, &quot;int&quot;, 0x0020, &quot;ptr&quot;, &amp;optval, &quot;int&quot;, 4)=0)
      return 1
    return 0
  }
}</code></pre></div>]]></description>
			<author><![CDATA[null@example.com (Dworkin)]]></author>
			<pubDate>Wed, 25 Jan 2017 12:09:11 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=111535#p111535</guid>
		</item>
	</channel>
</rss>
