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