News
 

DLLBinder Example - Chatterbox

To use this code, make sure you have downloaded the DLLBinder Pro V1.0.0 and String Handler V1.1.0 XTRAs.

Feel free to make use of this code in any way you want. If you make any great improvements, please send us a copy. Or if you have any other examples you would like to appear in these LIBRARY pages, please send it to info@the-mindseye.co.uk

Minds Eye Visualisation Services accepts no responibility for the reliability of any of the source code appearing in these pages. Use it at your own risk.

 

Requirements


DLLBinder pro


Minds Eye String Handler

 

Download zip Download Zip file   (chatterbox.zip - 92Kb)

------------------------------------------------------------------------
------------------------------------------------------------------------
-- SCRIPT NAME  sctTCPService
-- SCRIPT TYPE  Parent
-- DATE CREATED 10th February 2005
-- AUTHOR       Minds Eye Visualisation
-- PURPOSE      generic TCP message listening service.
--
------------------------------------------------------------------------
------------------------------------------------------------------------

property
 m_symStatus
property
 m_nPort
property
 m_nQueueLength
property
 m_oListenerThread
property
 m_oService
property
 m_hListeningSocket


------------------------------------------------------------------------
------------------------------------------------------------------------
-- FUNCTION  new
-- PURPOSE   child instance initialisation.
-- ACCESS    External 
------------------------------------------------------------------------
------------------------------------------------------------------------
on new me, nPort
  
  me
.m_oListenerThread=new(xtra "mevDllBinderPro")
  me
.m_oListenerThread.mevcDllLoad("ws2_32.dll")
  
  me
.m_oService=new(xtra "mevDllBinderPro")
  me
.m_oService.mevcDllLoad("ws2_32.dll")
  
  me
.m_symStatus=#ListenerStopped
  me
.m_nQueueLength=5
  
  me
.m_nPort=nPort
  
  return me

  
end


------------------------------------------------------------------------
------------------------------------------------------------------------
-- FUNCTION  GetStatus
-- PURPOSE   returns the TCP service status.
-- ACCESS    External 
------------------------------------------------------------------------
------------------------------------------------------------------------
on GetStatus me
  
  return me
.m_symStatus
  
end


------------------------------------------------------------------------
------------------------------------------------------------------------
-- FUNCTION  StartListening
-- PURPOSE   creates a listening socket and starts listening for new
--           client connections. moves to a #ListenerRunning state.
-- ACCESS    External 
------------------------------------------------------------------------
------------------------------------------------------------------------
on StartListening me
  
  if
 (me.m_symStatus=#ListenerStopped) then
    
    me
.OpenSocket()
    
    me
.Bind()
    
    me
.Listen()
    
    me
.Accept()
    
    me
.m_symStatus=#ListenerRunning
    
  end if

  
end


------------------------------------------------------------------------
------------------------------------------------------------------------
-- FUNCTION  StopListening
-- PURPOSE   closes the listening socket and so stops listening for new 
--           client connections. moves to a #ListenerStopping state.
-- ACCESS    External 
------------------------------------------------------------------------
------------------------------------------------------------------------
on StopListening me
  
  if
 (me.m_symStatus=#ListenerRunning) then
    
    --stop listening  
    me.CloseSocket(m_hListeningSocket)
    
    me
.m_symStatus=#ListenerStopping
    
  end if
 
  
end


------------------------------------------------------------------------
------------------------------------------------------------------------
-- FUNCTION  ReceiveNewConnection
-- PURPOSE   waits for new client connections. if the listening socket
--           has been closed then the listener thread will exit and the
--           service will move from a #ListenerStopping state to a 
--           #ListenerStopped state. if a new connection has been 
--           received the thread exits and returns the socket handle to
--           the new connection; a new listening thread is started 
--           immediately and the new connection socket is returned to 
--           the caller.
--
-- ACCESS    External 
------------------------------------------------------------------------
------------------------------------------------------------------------
on ReceiveNewConnection me
  
  hSocket=0

  
  if
 (me.m_oListenerThread.mevcGetStatus()=#ThreadRunning)  then
    
    lstInputArgs=[[]]
    lstRetVal=[]
    
    --check for newly accepted connections  
    if (me.m_oListenerThread.mevcGetFunThreadResults(\
               lstInputArgs,\
               lstRetVal)) then

      
      hSocket=lstRetVal[1
]
      
      if
 (hSocket > 0) then
        
        --prepare to accept the next connection?
        if (me.m_symStatus=#ListenerRunning) then                    
          me
.Accept()
          
        else if
 (me.m_symStatus=#ListenerStopping) then
          me
.m_symStatus=#ListenerStopped
          
        end if

        
      else if
 (me.m_symStatus=#ListenerStopping) then        
        me
.m_symStatus=#ListenerStopped
        
      else
        
        me
.m_symStatus=#ListenerError
        
      end if

      
    end if

    
  else
 --thread is not running but should be
    alert "listening thread not running"
    halt
()
  end if

  
  return
 hSocket
  
end


------------------------------------------------------------------------
------------------------------------------------------------------------
-- FUNCTION  WSAStartup
-- PURPOSE   initialises Winsock TCP.
--
-- ACCESS    External
--
------------------------------------------------------------------------
-- C API INFO                                  (see MSDN for more info)
--
--  #define WSADESCRIPTION_LEN      256
--  #define WSASYS_STATUS_LEN       128
--
--  typedef struct WSAData 
--  {
--        WORD                    wVersion;
--        WORD                    wHighVersion;
--        char                    szDescription[WSADESCRIPTION_LEN+1];
--        char                    szSystemStatus[WSASYS_STATUS_LEN+1];
--        unsigned short          iMaxSockets;
--        unsigned short          iMaxUdpDg;
--        char FAR *              lpVendorInfo;
--  } 
--
--  int WSAStartup (
--         WORD wVersionRequested,  
--         LPWSADATA lpWSAData);
--
--  the value for the wVersionRequested arg is 514
--
------------------------------------------------------------------------
------------------------------------------------------------------------
on WSAStartup me
  
  strFnName="WSAStartup"

  
  strPtrWSADataFormat="*{W,W,S257,S129,W,W,s256}"

  lstWSAData=[0
,0,"","",0,0,""]
  
  strInputArgFormat="W,"
 & strPtrWSADataFormat
  lstInputArgs=[514
, lstWSAData]
  
  strRetValFormat="d"

  lstRetVal=[]
  
  nErr=me
.m_oService.mevcCallDllFun(\
                strFnName, \
                strInputArgFormat,\
                lstInputArgs,\
                strRetValFormat,\
                lstRetVal)
    
end


------------------------------------------------------------------------
------------------------------------------------------------------------
-- FUNCTION  WSACleanup
-- PURPOSE   releases Winsock TCP resources.
-- ACCESS    External 
--
------------------------------------------------------------------------
-- C API INFO                                  (see MSDN for more info)
--
--   int  WSACleanup (void);
--
------------------------------------------------------------------------
------------------------------------------------------------------------
on WSACleanup me
  
  strFnName="WSACleanup"

  
  strInputArgFormat=""

  lstInputArgs=[]
  
  strRetValFormat="d"

  lstRetVal=[]
  
  nErr=me
.m_oService.mevcCallDllFun(\
                strFnName, \
                strInputArgFormat,\
                lstInputArgs,\
                strRetValFormat,\
                lstRetVal)
  
end


------------------------------------------------------------------------
------------------------------------------------------------------------
-- FUNCTION  Htons
-- PURPOSE   converts a number to network byte order.
-- ACCESS    Internal 
--
------------------------------------------------------------------------
-- C API INFO                                  (see MSDN for more info)
--
--   u_short htons(u_short hostshort);
--
------------------------------------------------------------------------
------------------------------------------------------------------------
on Htons me, nVal
  
  strFnName="htons"

  
  strInputArgFormat="W"

  lstInputArgs=[nVal]
  
  strRetValFormat="W"

  lstRetVal=[]
  
  nErr=me
.m_oService.mevcCallDllFun(\
                strFnName, \
                strInputArgFormat,\
                lstInputArgs,\
                strRetValFormat,\
                lstRetVal)
  
  return
 lstRetVal[1]
  
end


------------------------------------------------------------------------
------------------------------------------------------------------------
-- FUNCTION  OpenSocket
-- PURPOSE   creates a socket, bound to a specific service provider,
--           in this case TCP.
-- ACCESS    Internal 
--
------------------------------------------------------------------------
-- C API INFO                                  (see MSDN for more info)
--
--   SOCKET socket(int af, int type, int protocol);
--
--  the SOCKET return value is a handle to our socket ie a DWORD
--  we pass the AF_INET constant to the af arg. this is defined as 
--  #define AF_INET      2  /* internetwork UDP, TCP, etc. */
--
--  we pass the SOCK_STREAM constant to the type arg. this is defined as 
--  #define SOCK_STREAM  1  /* stream socket */
--  
------------------------------------------------------------------------
------------------------------------------------------------------------
on OpenSocket me
  
  strFnName="socket"
  
  
  strInputArgFormat="d,d,d"

  lstInputArgs=[]
  lstInputArgs[1
]=2   -- AF_INET internetwork UDP, TCP, etc see above
  lstInputArgs[2]=1   --SOCK_STREAM  a stream socket, see above
  lstInputArgs[3]=0   
  
  strRetValFormat="d"

  lstRetVal=[]
  
  nErr=me
.m_oService.mevcCallDllFun(\
                strFnName, \
                strInputArgFormat,\
                lstInputArgs,\
                strRetValFormat,\
                lstRetVal)
  
  --set up listening socket handle
  me.m_hListeningSocket=lstRetVal[1]
  
end


------------------------------------------------------------------------
------------------------------------------------------------------------
-- FUNCTION  Bind
-- PURPOSE   associates a local address with a socket.
-- ACCESS    Internal 
--
------------------------------------------------------------------------
-- C API INFO                                  (see MSDN for more info)
--
--  struct sockaddr_in 
--  {
--    short   sin_family;
--    u_short sin_port;
--    struct  in_addr sin_addr;  //for our purposes this is a 32bit ref.
--    char    sin_zero[8];
--  };
--
--  int bind (
--    SOCKET s,                          
--    const struct sockaddr FAR *name,  
--    int namelen);
--
------------------------------------------------------------------------
------------------------------------------------------------------------
on Bind me
  
  strFnName="bind"
  
  
  --get the port number in network byte order
  nNBOPort=me.Htons(me.m_nPort) 
  
  strPtrSockaddrInFormat="*{w,W,r,S8}"

  lstSockaddrIn=[]
  lstSockaddrIn[1
]=2        --AF_INET internetwork UDP, TCP, etc
  lstSockaddrIn[2]=nNBOPort --the port number in network byte order 
  lstSockaddrIn[3]=0        --INADDR_ANY ie any addresses can connect
  lstSockaddrIn[4]=""
  
  strInputArgFormat="D,"
 & strPtrSockaddrInFormat & ",d"
  lstInputArgs=[]
  lstInputArgs[1
]=me.m_hListeningSocket --handle to the socket
  lstInputArgs[2]=lstSockaddrIn         --sockaddr_in structured data 
  lstInputArgs[3]=16                    --size of the sockaddr_in struct
  
  strRetValFormat="d"

  lstRetVal=[]
  
  nErr=me
.m_oService.mevcCallDllFun(\
                strFnName, \
                strInputArgFormat,\
                lstInputArgs,\
                strRetValFormat,\
                lstRetVal)
  
  
end


------------------------------------------------------------------------
------------------------------------------------------------------------
-- FUNCTION  Listen
-- PURPOSE   places a socket a state where it is listening for an 
--           incoming connection.
--
-- ACCESS    Internal 
--
------------------------------------------------------------------------
-- C API INFO                                  (see MSDN for more info)
--
--   int listen(SOCKET s, int backlog);
--
--   backlog is the maximum length of the queue of pending connections
--
------------------------------------------------------------------------
------------------------------------------------------------------------
on Listen me
  
  strFnName="listen"
  
  
  strInputArgFormat="D, d"

  lstInputArgs=[me
.m_hListeningSocket, me.m_nQueueLength]
  
  strRetValFormat="d"

  lstRetVal=[]
  
  nErr=me
.m_oService.mevcCallDllFun(\
                strFnName, \
                strInputArgFormat,\
                lstInputArgs,\
                strRetValFormat,\
                lstRetVal)
  
end


------------------------------------------------------------------------
------------------------------------------------------------------------
-- FUNCTION  Accept
-- PURPOSE   accepts an incoming connection attempt on a socket. 
--           This is a blocking call. it will not return until it has 
--           received something or the socket has been closed. Hence 
--           we call this function asynchronously in order to regain
--           immediate control.
--            
-- ACCESS    Internal 
--
------------------------------------------------------------------------
-- C API INFO                                  (see MSDN for more info)
--
--   SOCKET accept(
--              SOCKET s,                   
--              struct sockaddr FAR *addr,  
--              int FAR *addrlen);
--
--   see Bind comment above for sockaddr struct defn
------------------------------------------------------------------------
------------------------------------------------------------------------
on Accept me
  
  strFnName="accept"
  
  
  strPtrSockaddrInFormat="*{w,W,r,S8}"

  lstSockaddrIn=[] --here, we receive this structured info
  
  strInputArgFormat="D,"
 & strPtrSockaddrInFormat & ",*d"
  lstInputArgs=[]
  lstInputArgs[1
]=me.m_hListeningSocket --handle to the socket
  lstInputArgs[2]=lstSockaddrIn         --sockaddr_in client data 
  lstInputArgs[3]=16                    --sockaddr_in struct size
  
  strRetValFormat="d"

  lstRetVal=[]
  
  nErr=me
.m_oListenerThread.mevcCallDllFunThread(\
                 strFnName, \
                 strInputArgFormat,\
                 lstInputArgs,\
                 strRetValFormat)
  
end


------------------------------------------------------------------------
------------------------------------------------------------------------
-- FUNCTION  CloseSocket
-- PURPOSE   releases the socket. further references to the socket
--           will then fail with the error WSAENOTSOCK.
-- ACCESS    Internal 
--
------------------------------------------------------------------------
-- C API INFO                                  (see MSDN for more info)
--
--  int closesocket(SOCKET s);
--
------------------------------------------------------------------------
------------------------------------------------------------------------
on CloseSocket me, hSocket
  
  strFnName="closesocket"
  
  
  strInputArgFormat="D"

  lstInputArgs=[hSocket]
  
  strRetValFormat="d"

  lstRetVal=[]
  
  nErr=me
.m_oService.mevcCallDllFun(\
                strFnName, \
                strInputArgFormat,\
                lstInputArgs,\
                strRetValFormat,\
                lstRetVal)
    
end


------------------------------------------------------------------------
------------------------------------------------------------------------
--end of script


------------------------------------------------------------------------
------------------------------------------------------------------------
-- SCRIPT NAME  sctTCPClientServiceConn
-- SCRIPT TYPE  Parent
-- DATE CREATED 10th February 2005
-- AUTHOR       Minds Eye Visualisation
-- PURPOSE      generic TCP client connection object   
--              the handlers in this script as well as its purpose 
--              correspond closely to the handlers and purpose of the 
--              sctTCPServiceClientConn parent script in the chatterbox
--              service movie mevChatterboxService.dir
------------------------------------------------------------------------
------------------------------------------------------------------------

property
 m_nPort
property
 m_strHostName
property
 m_lstHostent
property
 m_hSocket
property
 m_oSender
property
 m_oReceiver
property
 m_oMessage
property
 m_nMaxMessageSize
property
 m_symStatus


------------------------------------------------------------------------
------------------------------------------------------------------------
-- FUNCTION  new
-- PURPOSE   child instance initialisation.
-- ACCESS    External 
------------------------------------------------------------------------
------------------------------------------------------------------------
on new me, strHostName, nPort
  
  me
.m_lstHostent=[]
  me
.m_nMaxMessageSize=512  
  
  
  me
.m_nPort=nPort
  me
.m_strHostName=strHostName
  
  me
.m_oSender=new(xtra "mevDllBinderPro")
  me
.m_oSender.mevcDllLoad("ws2_32.dll")
  
  me
.m_oReceiver=new(xtra "mevDllBinderPro")
  me
.m_oReceiver.mevcDllLoad("ws2_32.dll")
  
  me
.m_symStatus=#ConnectionClosed
  
  me
.m_lstHostent=["",0,0,0,0]
  
  return me

  
end


------------------------------------------------------------------------
------------------------------------------------------------------------
-- FUNCTION  OpenConnection
-- PURPOSE   establish a connection with the host service.
-- ACCESS    External 
------------------------------------------------------------------------
------------------------------------------------------------------------
on OpenConnection me
  
  --initially assume an error state   
  me.m_symStatus=#ConnectionError
  bOK=FALSE

  
  --if first character is a digit then assume IP format
  if integerp(integer(me.m_strHostName.char[1..1])) then
    
    nIPAddress=me
.GetIPAddress()
    bOK=me
.GetHostByAddress(nIPAddress)
    
  else
    
    
    bOK=me
.GetHostByName()
    
  end if

  
  if
 bOK then bOK=me.OpenSocket()
  
  if
 bOK then bOK=me.Connect()
  
  --if all ok then start waiting for msgs immediately
  if bOK then me.ReceivePacket()
  
  --can now move to #ConnectionOpen state
  if bOK then me.m_symStatus=#ConnectionOpen
  
  --return connection sucess/failure
  return bOK
  
end


------------------------------------------------------------------------
------------------------------------------------------------------------
-- FUNCTION  CloseConnection
-- PURPOSE   close a connection with the host service.
-- ACCESS    External 
------------------------------------------------------------------------
------------------------------------------------------------------------
on CloseConnection me
  
  me
.CloseSocket()
  
  me
.m_symStatus=#ConnectionClosing
  
end


------------------------------------------------------------------------
------------------------------------------------------------------------
-- FUNCTION  GetStatus
-- PURPOSE   returns the TCP service status.
-- ACCESS    External 
------------------------------------------------------------------------
------------------------------------------------------------------------
on GetStatus me
  
  return me
.m_symStatus
  
end


------------------------------------------------------------------------
------------------------------------------------------------------------
-- FUNCTION  SendStream
-- PURPOSE   sends a client message to the host service.
--           You should perform any message integrity tests here.
-- ACCESS    External 
------------------------------------------------------------------------
------------------------------------------------------------------------
on SendStream me, oMessage
  
  if
 oMessage.mevcGetLength() > me.m_nMaxMessageSize then
    alert
 "maximum message size exceeded!"
    halt
()    
  end if

  
  me
.SendPacket(oMessage)
  
end


------------------------------------------------------------------------
------------------------------------------------------------------------
-- FUNCTION  ReceiveStream
-- PURPOSE   receives any new messages; 
--           returns the current connection status.
-- ACCESS    External 
------------------------------------------------------------------------
------------------------------------------------------------------------
on ReceiveStream me
  
  oRetMsg=void

  
  if
 (me.m_oReceiver.mevcGetStatus()=#ThreadRunning) then
    
    lstInputArgs=[]
    lstRetVal=[]
    
    --check if this thread has completed 
    if (me.m_oReceiver.mevcGetFunThreadResults(\
                        lstInputArgs,\
                        lstRetVal)) then

      
      --if Win32 API return val > 0 its the length of the received msg
      if (lstRetVal[1]>0) then
        
        --copy member message stream ref to return val
        oRetMsg=me.m_oMessage
        
        --reset the message stream object to size of received stream
        oRetMsg.mevcSetBufferLength(lstRetVal[1])
        
        --start waiting for another new message stream?
        if me.m_symStatus=#ConnectionOpen then                  
          me
.ReceivePacket()                    
          
        else if me
.m_symStatus=#ConnectionClosing then                    
          me
.m_symStatus=#ConnectionClosed         
          
        end if
        
        
      else if me
.m_symStatus=#ConnectionClosing then                  
        me
.m_symStatus=#ConnectionClosed        
        
      else
 --treat as an error                 
        me.m_symStatus=#ConnectionError        
        
      end if

      
    end if
           
    
  else
 --thread is not running but should be
    alert "receiver thread not running"
    halt
()
  end if

  
  return
 oRetMsg
  
end


------------------------------------------------------------------------
------------------------------------------------------------------------
-- FUNCTION  WSAStartup
-- PURPOSE   initialise Winsock TCP.
-- ACCESS    External
--
------------------------------------------------------------------------
-- C API INFO                                  (see MSDN for more info)
--
--  #define WSADESCRIPTION_LEN      256
--  #define WSASYS_STATUS_LEN       128
--
--  typedef struct WSAData 
--  {
--        WORD                    wVersion;
--        WORD                    wHighVersion;
--        char                    szDescription[WSADESCRIPTION_LEN+1];
--        char                    szSystemStatus[WSASYS_STATUS_LEN+1];
--        unsigned short          iMaxSockets;
--        unsigned short          iMaxUdpDg;
--        char FAR *              lpVendorInfo;
--  } 
--
--  int WSAStartup (
--         WORD wVersionRequested,  
--         LPWSADATA lpWSAData);
--
--  the value for the wVersionRequested arg is 514
--
------------------------------------------------------------------------
------------------------------------------------------------------------
on WSAStartup me
  
  strFnName="WSAStartup"

  
  strPtrWSADataFormat="*{W,W,S257,S129,W,W,s256}"

  lstWSAData=[0
,0,"","",0,0,""]
  
  strInputArgFormat="W,"
 & strPtrWSADataFormat
  lstInputArgs=[514
, lstWSAData]
  
  strRetValFormat="d"

  lstRetVal=[]
  
  nErr=m_oSender.mevcCallDllFun(\
           strFnName, \
           strInputArgFormat,\
           lstInputArgs,\
           strRetValFormat,\
           lstRetVal)
  
end


------------------------------------------------------------------------
------------------------------------------------------------------------
-- FUNCTION  WSACleanup
-- PURPOSE   releases Winsock TCP resources.
-- ACCESS    External 
--
------------------------------------------------------------------------
-- C API INFO                                  (see MSDN for more info)
--
--   int  WSACleanup (void);
--
------------------------------------------------------------------------
------------------------------------------------------------------------
on WSACleanup me
  
  strFnName="WSACleanup"

  
  strInputArgFormat=""

  lstInputArgs=[]
  
  strRetValFormat="d"

  lstRetVal=[]
  
  nErr=m_oSender.mevcCallDllFun(\
           strFnName, \
           strInputArgFormat,\
           lstInputArgs,\
           strRetValFormat,\
           lstRetVal)
  
end


------------------------------------------------------------------------
------------------------------------------------------------------------
-- FUNCTION  Htons
-- PURPOSE   converts a number to network byte order.
-- ACCESS    Internal 
--
------------------------------------------------------------------------
-- C API INFO                                  (see MSDN for more info)
--
--           u_short htons(u_short hostshort);
--
------------------------------------------------------------------------
------------------------------------------------------------------------
on Htons me, nVal
  
  strFnName="htons"

  
  strInputArgFormat="W"

  lstInputArgs=[nVal]
  
  strRetValFormat="W"

  lstRetVal=[]
  
  nErr=m_oSender.mevcCallDllFun(\
           strFnName, \
           strInputArgFormat,\
           lstInputArgs,\
           strRetValFormat,\
           lstRetVal)
  
  return
 lstRetVal[1]
  
end



------------------------------------------------------------------------
------------------------------------------------------------------------
-- FUNCTION  GetHostByName
-- PURPOSE   resolves a host by its name.
-- ACCESS    Internal 
--
------------------------------------------------------------------------
-- C API INFO                                  (see MSDN for more info)
--
--  struct  hostent 
--  {
--        char    FAR * h_name;             /* official name of host */
--        char    FAR * FAR * h_aliases;    /* alias list */
--        short   h_addrtype;               /* host address type */
--        short   h_length;                 /* length of address */
--        char    FAR * FAR * h_addr_list;  /* list of addresses */
--  };
--
--  struct hostent FAR* WSAAPI gethostbyname(const char FAR * name);
--
------------------------------------------------------------------------
------------------------------------------------------------------------
on GetHostByName me
  
  bRet=FALSE

  
  strFnName="gethostbyname"
  
  
  strInputArgFormat="s128"

  lstInputArgs=[me
.m_strHostName]
  
  
  strRetValFormat="r"
 --ref to the hostent struct
  lstRetVal=[]
  
  nErr=m_oSender.mevcCallDllFun(\
           strFnName, \
           strInputArgFormat,\
           lstInputArgs,\
           strRetValFormat,\
           lstRetVal)
  
  --if the return value is > 0 then its the adress of a hostent struct
  if lstRetVal[1] > 0 then
    
    lstGetValList=[me
.m_lstHostent]
    strPtrHostentFormat="{s256,r,w,w,r}"
          
    
    m_oSender.mevcMemGetValues(\
           lstRetVal[1
],\
           strPtrHostentFormat,\
           lstGetValList)
    
    bRet=TRUE

    
  else
 --can use WSAGetLastError to find out more about the error
  end if
  
  return
 bRet
  
end


------------------------------------------------------------------------
------------------------------------------------------------------------
-- FUNCTION  GetHostByAddress
-- PURPOSE   resolves a host by its numerical address.
-- ACCESS    Internal 
--
------------------------------------------------------------------------
-- C API INFO                                  (see MSDN for more info)
--
--  struct HOSTENT FAR * gethostbyaddr(
--    const char FAR *addr,  
--    int len,                
--    int type);
--
--  see above for HOSTENT definition
--
------------------------------------------------------------------------
------------------------------------------------------------------------
on GetHostByAddress me, nIPAddress
  
  bRet=FALSE

  
  strFnName="gethostbyaddr"
  
  
  strInputArgFormat="*D,d,d"
 --note we must pass nIPAddress by reference
  lstInputArgs=[]
  lstInputArgs[1
]=nIPAddress
  lstInputArgs[2
]=4   --this is the size of nIPAddress ie a 32bit int
  lstInputArgs[3]=2   --AF_INET internetwork UDP, TCP, etc
  
  strRetValFormat="r"
 --ref to the hostent struct
  lstRetVal=[]
  
  nErr=m_oSender.mevcCallDllFun(\
           strFnName, \
           strInputArgFormat,\
           lstInputArgs,\
           strRetValFormat,\
           lstRetVal)
  
  --if the return value is > 0 then its the address of a hostent struct
  if lstRetVal[1] > 0 then
    
    lstGetValList=[me
.m_lstHostent]
    strPtrHostentFormat="{s256,r,w,w,r}"
          
    
    m_oSender.mevcMemGetValues(\
           lstRetVal[1
],\
           strPtrHostentFormat,\
           lstGetValList)
    
    bRet=TRUE
 
    
  else
 --can use WSAGetLastError to find out more about the error        
  end if
  
  return
 bRet
  
end


------------------------------------------------------------------------
------------------------------------------------------------------------
-- FUNCTION  GetIPAddress
-- PURPOSE   returns an IP address string as an 32bit unsigned int.
--           IP string has format of four bytes in dotted notation ie 
--           b.b.b.b
-- ACCESS    Internal 
--
------------------------------------------------------------------------
-- C API INFO                                  (see MSDN for more info)
--
--  unsigned long inet_addr (const char FAR *cp);
--
------------------------------------------------------------------------
------------------------------------------------------------------------
on GetIPAddress me
  
  strFnName="inet_addr"
  
  
  strInputArgFormat="s32"
 --note we must pass nIPAddress by reference
  lstInputArgs=[me.m_strHostName]
  
  strRetValFormat="D"
  
  lstRetVal=[]
  
  nErr=m_oSender.mevcCallDllFun(\
           strFnName, \
           strInputArgFormat,\
           lstInputArgs,\
           strRetValFormat,\
           lstRetVal)
  
  return
 lstRetVal[1]  
  
end


------------------------------------------------------------------------
------------------------------------------------------------------------
-- FUNCTION  OpenSocket
-- PURPOSE   creates a socket, bound to a specific service provider,
--           in this case TCP.
-- ACCESS    Internal 
--
------------------------------------------------------------------------
-- C API INFO                                  (see MSDN for more info)
--
--   SOCKET socket(int af, int type, int protocol);
--
--  the SOCKET return value is a handle to our socket ie a DWORD
--  we pass the AF_INET const to the af arg. this is defined as 
--  #define AF_INET      2  /* internetwork UDP, TCP, etc. */
--
--  we pass the SOCK_STREAM const to the type arg. this is defined as 
--  #define SOCK_STREAM  1  /* stream socket */
--  
------------------------------------------------------------------------
------------------------------------------------------------------------
on OpenSocket me
  
  bRet=FALSE

  
  strFnName="socket"
  
  
  strInputArgFormat="d,d,d"

  lstInputArgs=[]
  lstInputArgs[1
]=2  --AF_INET internetwork UDP, TCP, etc see above
  lstInputArgs[2]=1  --SOCK_STREAM  a stream socket, see above
  lstInputArgs[3]=0   
  
  strRetValFormat="d"

  lstRetVal=[]
  
  nErr=m_oSender.mevcCallDllFun(\
           strFnName, \
           strInputArgFormat,\
           lstInputArgs,\
           strRetValFormat,\
           lstRetVal)
  
  --get the returned socket handle
  
  if
 lstRetVal[1] > 0 then --its valid
    m_hSocket=lstRetVal[1]
    bRet=TRUE
 
    
  else
 --can use WSAGetLastError to find out more about the error       
  end if
  
  return
 bRet
  
end


------------------------------------------------------------------------
------------------------------------------------------------------------
-- FUNCTION  Connect
-- PURPOSE   attempts to connect to the host listening port.
-- ACCESS    Internal 
--
------------------------------------------------------------------------
-- C API INFO                                  (see MSDN for more info)
--
--  struct sockaddr_in 
--  {
--    short   sin_family;
--    u_short sin_port;
--    struct  in_addr sin_addr;  //for our purposes this is a 32bit ref.
--    char    sin_zero[8];
--  };
--
--  int connect (
--    SOCKET s,                          
--    const struct sockaddr FAR *name,  
--    int namelen);
--
------------------------------------------------------------------------
------------------------------------------------------------------------
on Connect me
  
  bRet=FALSE

  
  --first we need to de-reference the ref to the address list
  --which is the fifth member of the returned hostent struct  
  lstGetValList=[]
  m_oSender.mevcMemGetValues(me
.m_lstHostEnt[5], "*r", lstGetValList)
  
  strFnName="connect"
  
  
  --get the port number in network byte order
  nNBOPort=me.Htons(me.m_nPort) 
  
  strPtrSockaddrInFormat="*{w,W,r,S8}"

  lstSockaddrIn=[]
  lstSockaddrIn[1
]=2            --AF_INET internetwork UDP, TCP etc
  lstSockaddrIn[2]=nNBOPort     --port in network byte order 
  lstSockaddrIn[3]=lstGetValList[1--list of addresses
  lstSockaddrIn[4]=""
  
  strInputArgFormat="D,"
 & strPtrSockaddrInFormat & ",d"
  lstInputArgs=[]
  lstInputArgs[1
]=me.m_hSocket   --handle to the socket
  lstInputArgs[2]=lstSockaddrIn  --sockaddr_in structured data 
  lstInputArgs[3]=16             --size of the sockaddr_in structure
  
  strRetValFormat="d"

  lstRetVal=[]
  
  nErr=m_oSender.mevcCallDllFun(\
           strFnName, \
           strInputArgFormat,\
           lstInputArgs,\
           strRetValFormat,\
           lstRetVal)
  
  --skeleton error handling.
  if lstRetVal[1]=0 then --all ok
    bRet=TRUE
    
  else
 --can use WSAGetLastError to find out more about the error    
  end if
  
  return
 bRet
  
end


------------------------------------------------------------------------
------------------------------------------------------------------------
-- FUNCTION  SendPacket
-- PURPOSE   sends a packet of data to the host service.
-- ACCESS    Internal 
--
------------------------------------------------------------------------
-- C API INFO                                  (see MSDN for more info)
--
--  int send(
--      SOCKET s,
--      const char FAR * buf,
--      int len,
--      int flags);
--
------------------------------------------------------------------------
------------------------------------------------------------------------
on SendPacket me, oMessage
  
  strFnName="send"
  
      
  strInputArgFormat="D,r,d,d"

  lstInputArgs=[]
  lstInputArgs[1
]=me.m_hSocket                --the handle to the socket
  lstInputArgs[2]=oMessage.mevcGetStringPtr() --packet string reference
  lstInputArgs[3]=oMessage.mevcGetLength()    --size of the packet
  lstInputArgs[4]=0                           --default flags val
  
  strRetValFormat="d"

  lstRetVal=[]
  
  nErr=m_oSender.mevcCallDllFun(\
           strFnName, \
           strInputArgFormat,\
           lstInputArgs,\
           strRetValFormat,\
           lstRetVal)
  
end


------------------------------------------------------------------------
------------------------------------------------------------------------
-- FUNCTION  ReceivePacket
-- PURPOSE   receives a packet of data from the host service.
-- ACCESS    Internal 
------------------------------------------------------------------------
-- C API INFO                                  (see MSDN for more info)
--
--  This is a blocking call. it will not return until it has received
--  something or the connection is dropped
--
--  int recv(
--          SOCKET s,
--          char FAR * buf,
--          int len,
--          int flags
--          );
--
------------------------------------------------------------------------
------------------------------------------------------------------------
on ReceivePacket me
  
  --create a new message stream
  me.m_oMessage=new(xtra"mevString")
  me
.m_oMessage.mevcSetBufferLength(me.m_nMaxMessageSize)
  
  strFnName="recv"
  
  
  strInputArgFormat="D,r,d,d"

  lstInputArgs=[]
  lstInputArgs[1
]=me.m_hSocket                     --the socket handle 
  lstInputArgs[2]=me.m_oMessage.mevcGetStringPtr() --packet string ref
  lstInputArgs[3]=me.m_nMaxMessageSize             --max packet size 
  lstInputArgs[4]=0                                --default flags val
  
  strRetValFormat="d"

  lstRetVal=[]
  
  --make an asynchronous call so that we get control back immediately
  nErr=me.m_oReceiver.mevcCallDllFunThread(\
              strFnName, \
              strInputArgFormat,\
              lstInputArgs,\
              strRetValFormat)
  
end


------------------------------------------------------------------------
------------------------------------------------------------------------
-- FUNCTION  CloseSocket
-- PURPOSE   releases the socket. further references to the socket
--           will then fail with the error WSAENOTSOCK.
-- ACCESS    Internal 
--
------------------------------------------------------------------------
-- C API INFO                                  (see MSDN for more info)
--
--  int closesocket(SOCKET s);
--
------------------------------------------------------------------------
------------------------------------------------------------------------
on CloseSocket me
  
  strFnName="closesocket"
  
  
  strInputArgFormat="D"

  lstInputArgs=[me
.m_hSocket]
  
  strRetValFormat="d"

  lstRetVal=[]
  
  nErr=m_oSender.mevcCallDllFun(\
           strFnName, \
           strInputArgFormat,\
           lstInputArgs,\
           strRetValFormat,\
           lstRetVal)
  
end


------------------------------------------------------------------------
------------------------------------------------------------------------
--end of script



------------------------------------------------------------------------
------------------------------------------------------------------------
-- SCRIPT NAME  sctTCPServiceClientConn
-- SCRIPT TYPE  Parent
-- DATE CREATED 10th February 2005
-- AUTHOR       Minds Eye Visualisation
-- PURPOSE      generic TCP client connection object.
--              the handlers in this script as well as its purpose 
--              correspond closely to the handlers and purpose of the 
--              sctTCPClientServiceConn parent script in the chatterbox
--              client movie mev