þÿ<HTML> <HEAD> <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1"> <TITLE>TN06a: Alternatives to WinSock</TITLE> <link rel="stylesheet" href="/style2.css"> </HEAD> <BODY TEXT="#000000" LINK="#0000ff" VLINK="#800080" BGCOLOR="#ffffff"> <TABLE CELLSPACING=0 BORDER=0 WIDTH=478> <TR><TD WIDTH="22%" VALIGN="TOP"> <P><IMG SRC="images/BigIcon.GIF" WIDTH=86 HEIGHT=103></TD> <TD WIDTH="78%" VALIGN="TOP"> <B><FONT FACE="Helvetica" SIZE=5> <h2>Tech Note TN06a: Alternatives to WinSock: IPWorks and NewObjects</h2> </FONT></B> <h3><B><FONT FACE="Helvetica">August 7, 2007 </FONT><FONT FACE="Helvetica" SIZE=4> </FONT></B> </h3> <h5><b><font face="Helvetica">© 2010 NS BASIC Corporation. All rights reserved. </font></b></h5> </TD> </TR> </TABLE> <HR> <i>Contributed by an NS Basic/CE user who wishes to remain anonymous</i> <p>Ever try to use Winsock with NSBasic? Good luck. I wasted about a week trying to get Winsock to communicate to a TCP/IP server and found it to be buggy and basically unusable except for all but the most primitive of applications. <p>I found two NSBasic compatible third party alternatives for Winsock and elected to work with IPWorks ActiveX. I decided to share what I learned to help the next person to follow in my footsteps and as a gesture of thanks to George Henne of NSBasic and Tony Hito of /nSoftware for their assistance during the process. <h4>Background</h4> For two NSBasic compatible tcp/ip controls check out: <a href="http://www.newobjects.com/productlist.asp?Category=ServerActiveX" target="_top">http://www.newobjects.com/productlist.asp?Category=ServerActiveX</a> <p>and look for a product called AxPack which freeware. It is also distributed with NS Basic//CE for use with SQLite. <p>and <a href="http://www.nsoftware.com/download/default.aspx?filter=activex" target="_top">http://www.nsoftware.com/download/default.aspx?filter=activex</a> <p>then select download archive and look for the ActiveX Edition V5 described as: IP*Works! V5 ActiveX Edition for Pocket PC 2002 32 bit ActiveX Controls Version 5.0.1508. It looks like there are several offerings and I m not positive as I write this which one you need but you want to make sure that the version you purchase includes the files for use with Visual Basic and Pocket PC. Why? Because you will need the VB files to get the license key needed in your NSBasic project; more on that later. My invoice from /n Software was for part# IPA5-X and the description is IP*Works V5 ActiveX Ed/Win CE. <p>This version is obsolete but still sold and supported with limitations. Special pricing is available for NSBasic customers. Contact George at NSBasic or Tony Hito at IPWorks. <p>I selected IPWorks vs New Objects because I felt IPWorks products were better documented, had better samples, were designed for high level programming and would ultimately save me money by saving me time. <p>The downsides of the IPWorks product is that it is an obsolete version that will not be patched with bug fixes unless IPWorks has a change of heart and it is pricey compared to AxPack. <p>With IPWorks all you need to do to communicate with a tcp/ip server is to set the IP address, port address and figure out how to use a few simple commands and respond to a few simple events. Unless I misunderstood, New Objects requires much more effort. <h4>IPWorks:</h4> <pre> telnet1.localhost=ipaddress of host telnet1.localport=local port address telnet1.remoteport=remote port address (same as local port address in my case) telnet1.connect = true </pre> <p>Send data to the server with <pre> telnet1.send datastring </pre> <p>Pick up data sent back from the server in the <pre> telnet1_DataIn(incomingdata) </pre> sub. <p>The Telnet1_Connected fires when your program (the client) connects to the host and Telnet1_Disconnected fires when your program disconnects from the host. You initiate a disconnect setting Telnet1.connected = false or call telnet1.disconnect. I found I had to set telnet1.linger=false before disconnecting else on a reconnect I got a Winsock 10048 error (same as VB 25049 error). <p>There isn t much more to know about using IPWorks product; it s a simple but elegant product that works well. <h4>AxPack:</h4> <p>I found NewObjects web site confusing, explanations lacking and direction of the company and product difficult to ascertain. I got the impression (perhaps incorrectly) that tcp/ip capability offered within AxPack was constructed as an add on to AxPack core capabilities and this complicated implementation but may enhance capabilities for your project. <p>Say for example you want to use AxPack to read/write to a file. If you bolt on tcp/ip you now can direct data from their tcp/ip add on to other resources if I understand correctly. This requires a deeper understanding of the AxPack product to implement simple tcp/ip communications and this is borne out if you read the (confusing) documentation and sparse samples. <p>Some programmers might enjoy getting deeper into the bowels of the control; for me I just want to get the job done and prefer a higher level solution. <p>What I did see with AxPack that looked intriguing is a complete toolset of Com controls that are not dependent on other technologies, everything from string manipulation to file management and tcp/ip. There is a lot there and its designed with the PDA in mind. <h4>Using IPWorks with NSBasic</h4> <p>NS Basic/CE is a late-binding language. Controls are not added to the project until runtime so you must take responsibility for registering the third party control and for providing a legal license key. <p>IPWorks 5 ships with several flavors of each type of control. I used the telnet control in my app; it s named tnt50.ocx and there are 3 versions available in the package; one for visual basic and two flavors (ARM or x86) for Win CE/Pocket PC. <h4>Which control is the right one?</h4> <p>The simplest way to determine which ocx is right for your PDA is to do a quick experiment: <pre> C:\Program Files\IPWorks V5\ActiveX Edition\wce300\Pocket PC 2002\ARM\tnt50.ocx C:\Program Files\IPWorks V5\ActiveX Edition\wce300\Pocket PC 2002\x86\tnt50.ocx C:\Program Files\IPWorks V5\ActiveX Edition\lib\tnt.ocx </pre> <p>Using Microsoft ActiveSync Explorer copy the first file to the \windows directory on the PDA then make an attempt to register the control. <p>The simplest way to do this is to write a NSBasic app that registers an OCX. My NSBasic code has a form with a button and when the user clicks the button I run this sub: <pre> Sub RegisterControl Dim tmp tmp = "\windows" 'Register a third party control ShellExecute "open","regsvrce.exe",tmp & "\tnt50.ocx" End Sub </pre> <p>One of the first two files should register correctly; when it does you ll know which file to include with your package. <h4>Entering the License Key:</h4> <p>IPWorks is designed to be used with compiled languages that offer early binding so entering the license key on a NSBasic application, although easy, requires some home work. <p>IPWorks has a web site to enable their product to be used in a development environment. Get the most current web address from IPWorks and use it to enable your desktop PC. <p>With your desktop PC enabled use a program like Microsoft s Visual Basic and create an application using the VB compatible tnt.ocx control. For VB beginners: you add a control to a project by clicking project then components and the /nSoftware control will show up on a list. Click the control you want to use and it will then show in the VB toolbox and can be placed on a VB form. <p>I suspect you could use vbscript if you don t have Visual Basic; we ll leave it to George Henne to create a sample VBScript app for NSBasic programmers who need to take this step. <p>With Visual Basic I load my control into a new project and run this code in form_load <pre> Debug.print telnet1.ok </pre> <p>This prints the contents of the telnet1 license key (which is known because the desktop PC is licensed to use the developer version of IPWorks 5) to the debugger. <p>Run the program by pressing f5. <p>Select the string printed to the vb debugger (accessed with CTRL+G) and paste it into your NSBasic project with surrounding quotes like this: <pre> telnet1.ok = the string you received from the vb project  </pre> <p>That s all there is too it. Now your NSBasic project will not complain about an unlicensed tnt.ocx control. <h4>Writing your first tcp/ip client program:</h4> This code is a framework for a tcp/ip application that first connects to a tcp/ip server, logs on and then does nothing. Once you are logged on you can enhance the code to send data to the server using telnet1.send datatosend  and monitor for a response in telnet1_DataIn(datareceived) event. You disconnect using telnet1.connected = false. <pre> first load the third party control into the project, see below to learn how to get its name how did I know what control name to use? use a pda registry editor to figure this out. You can get a free one get one for looking only called called TTXN Remote Registry Editor (search google to find if needed) http://www.soft32.com/Download/free-trial/Remote_Registry_Editor/4-158680-4.html you ll find what you are looking for in Hkey-Classes-Root, my guess is the  registry name cross references the clsid of the control On Error resume next AddObject "IPWorks.Telnet","Telnet1",0,0,0,0 'obj id, var name, location 0000 If err Then MsgBox "failed to load tnt50.ocx " & TypeName(telnet1) Bye End If On Error Goto 0 'enter license telnet1.ok="mylicense string from ipworks  'put some buttons on a NSBasic form to enter IPAddress and Port and a connect button, I also added a box for a logon id and possibly a password for logging on to the tcp/ip server. My app is for delivery drivers so each driver has his/her own logon id our tcp/Ip server sends back a bunch of garbage after logging in and I wanted to shut this off so note the use of telnet1.acceptdata=false Sub cmdConnect_Click If tbIP.Text = "" Then MsgBox "You must define an IP address!" exit Sub End If If Not IsNumeric(tbport.Text) Then MsgBox "You must define a valid PortNo!" exit Sub End If If tbdriver.Text = "" Then MsgBox "You must define a Driver ID to Logon.":exit Sub End If 'see bp sendsig on monster for test program telnet1.acceptdata = False 'stop logon garbage, set to true when logon complete telnet1.localport =CInt(tbport.Text) telnet1.remotePort=CInt(tbPort.text) telnet1.remotehost = tbip.Text On Error resume next I kept getting a Winsock 10048 error which implies the winsock control is in use so I tried this strategy to force a disconnect, but it doesn t seem to work telnet1.linger = false needed for an immediate disconnect telnet1.connected = False 'just in case 10048 error if you are connected already and try to reconnect doevents telnet1.doevents() if you find that you get a Winsock 10048 error or a VB 25045 error (same error as Winsock 10048 with a 2 nd connection after disconnecting the 1 st you should separate this section into something more sophisticated; I had a problem with the 10048 error before setting linger = false and set up a do while loop to call a function repeatedly until a timeout value was reached or my connection succeeded; I think setting linger = false will do it for you on error goto 0 telnet1.connected = True connect to the server End Sub you ll need to put some code in an event to process incoming data Sub Telnet1_DataIn(incoming) 'DATA HAS ARRIVED from server, our server added a chr(0) at the end of some strings and sometimes sent an extra vbcrlf & chr(0) so I filter those out before processing Dim i,x If right(incoming,1)=chr(0) then incoming = Left(incoming,x-1) If incoming=vbcrlf Then exit Sub 'seems to be necessary 0906076 End If do more work here, you have data that needs to be processed from server this is where I watch for tcp\ip messages from server such as logonok  sent by my server program after successful logon End Sub once connected to the tcp/ip server we want to logon Sub onConnect() 'remember: telnet1.acceptdata = False was set in cmdconnect our tcp/ip server needs a vbcrlf to send back a logon prompt telnet1.send vbcrlf attract the attention of the server now sleep for a bit to give the server a chance to respond For i = 1 To 100 Call Sleep(10) DoEvents Next accept incoming data telnet1.acceptdata = True 'accept data again send logon (with password if appropriate) telnet1.send tbDriver.Text & vbcrlf 'send logon my tcp/ip server program sends back the string logonok  if logon is successful, watch for this in telnet_DataIn to know that you are logged on Call refreshbuttons  I found my pda buttons needed refreshing or they got weird, no code supplied for this, but basically I assign the content of a control to a variable and reassign the .text or .caption property to the variable which seems to work well to refresh the control End Sub you want to do something once you are connected Sub Telnet1_Connected(StatusCode, Description) Dim i 'statuscode=0 when connected If StatusCode <> 0 Then tbstatus.Text = "Connection: " & Description Else tbstatus.Text = "Connected: " & description DoEvents Call OnConnect logon to tcp/ip server End If End Sub and when you disconnect Sub Telnet1_DisConnected(StatusCode, Description) Dim i 'statuscode=0 when disconnected If StatusCode <> 0 Then tbstatus.Text = "Connection: " & Description Else tbstatus.Text = "Connected: " & description Call OnDisConnect End If End Sub Sub OnDisconnect do whatever it is you want to do when disconnected from tcp/ip server end sub </pre> </P></BODY> </HTML>