here is a sample code for using winsock.
from
http://fox.wikis.com/wc.dll?Wiki~WinSockOCX_Sample~VFPHow to use these 3 classes in my form ?
* --- WinSock ActiveX Abstract
DEFINE CLASS aWinSock AS OleControl
OleClass = "MSWinsock.Winsock"
PROCEDURE Init
This.protocol = Thisform.nProtocol
This.localport = Thisform.nPort
ENDPROC
PROCEDURE Error
LPARAMETERS number, description, scode, source, helpfile, helpcontext, canceldisplay
* It's used for error displaying purposes
WITH ThisForm.EditOut
.Value = .Value + CHR(13) + CHR(10)
.Value = .Value + 'Error ' + STR(number) + " " + ;
Description + chr(13) + chr(10)
.Refresh()
ENDWITH
ENDPROC
ENDDEFINE
* --- WinSock ActiveX "the listener"
DEFINE CLASS frmSock AS aWinSock
* Because it might be, that we want to have more than one single
* connection active, we need a method to do a pseudo multi
* threading. I have "stolen" this idea from EETAServer ---
* Thx btw --- and have later on noticed that this already is
* recommended in the online help.
PROCEDURE ConnectionRequest
LPARAMETER tnRequestID
* This ActiveX is a performance hog, so we need to get
* rid of older connections that aren't active anymore.
* So before adding a new one we check if we can skip
* another.
FOR EACH lControl IN ThisForm.Controls
* This DoEvent might not really be necessary, but
* it helps to get a correct state from the instance
DOEVENTS
IF LOWER(lControl.Class) != 'frmsock2' or ;
((seconds()-lControl.nCreateTime) < 5 or lControl.State = 7)
LOOP
ENDIF
* If we have an instance to skip we show this to the user
WITH ThisForm.EditOut
.Value = .Value + 'Info ' + 'Remove ' + lControl.name + chr(13) + chr(10)
.Refresh()
EndWith
Thisform.RemoveObject(lControl.name )
ENDFOR
* Now let's add another TCP server, that is able to handle
* the intended connection. The SYS(2015) function is a simple
* way to get an almost unique object name. In a serious production
* app it might be necessary to catch it's weaknesses for fast
* consequtive calls.
ThisForm.Addobject( SYS(2015), 'frmSock2', m.tnRequestID )
* If we have an instance to add we also show this to the user
WITH ThisForm.EditOut
.Value = .Value + 'Info ' + 'Connection added ID ' + ;
STR(m.tnRequestID) + chr(13) + chr(10)
.Refresh()
ENDWITH
RETURN
ENDPROC
ENDDEFINE
* --- WinSock ActiveX for multiple Connections
DEFINE CLASS frmSock2 AS aWinSock
nCreateTime = 0 && The creation time
cReceiveBuffer = '' && a buffer to stitch incomming transmission together
PROCEDURE Init
LPARAMETERS tnRequestID
LOCAL llRetVal
This.nCreateTime = SECONDS()
This.Accept(tnRequestID)
ThisForm.nstat = this.State
ThisForm.Refresh()
RETURN
ENDPROC
PROCEDURE DataArrival
LPARAMETERS tnByteCount
LOCAL lcBuffer
lcBuffer = SPACE(tnByteCount)
* This gets the data from the socket. It can happen, that the data isn't
* received in a single rush. Thus we need a EOT (end of transmission)
* sign to be sure, the data is complete. Until we get this, the data
* is stuffed into cReceiveBuffer.
This.GetData( @lcBuffer, , tnByteCount )
IF AT( EOT, lcBuffer ) = 0 && Not yet finished
This.cReceiveBuffer = This.cReceiveBuffer + lcBuffer
ELSE
This.cReceiveBuffer = This.cReceiveBuffer + LEFT( lcBuffer, AT( EOT, lcBuffer ) -1 )
* First we strip off the EOT sign that has done it's purpose ...
* then follows the "real" action. All we want to do should be done
* here now. For a sample we show the incoming text in an
* editbox
WITH ThisForm.EditOut
.Value = .Value + This.cReceiveBuffer + CHR(13) + CHR(10)
.Refresh()
ENDWITH
* But we can do a lot more of course eg ...
* return the time of the servers machine when we get a request
* for it ...
IF UPPER( LEFT( This.cReceiveBuffer, 7 ) ) = 'GETTIME'
* Again in a production app we would have to be a little
* more careful. If the connection got lost meanwhile this
* returns an ugly error with a a popping up Messagebox :-(
This.SendData( TTOC(datetime()) + EOT )
ENDIF
* Finally the receive Buffer has to be cleared again to
* be ready for the next transmission
This.cReceiveBuffer = ''
ENDIF
RETURN
ENDPROC
PROCEDURE Close
This.Object.Close()
ENDPROC
ENDDEFINE