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  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



  3d visualisation     data visualisation     interactive cds     printing     software     web design     training     games  
© Copyright 2006. Minds Eye Visualisation Services Limited. All Rights Reserved.