Introduction
If you have followed all the examples to create a TINE client or server then your server or client stands a good chance of working right off the bat. However, if you are experiencing difficulties getting your programs to run correctly nothing is more frustrating than having no idea what to look for to solve the problem. Below are some tips as to what to look for in solving problems you might have. It is assumed that you have successfully linked and compiled your server or client. If you have problems compiling or linking, then you should double check your project.def file and your .mak file to make sure it is for your target platform.
Server Problems
I started my server and it looks happy, but I can’t see it on the net!
1). Check the connectivity.
- Is the IP address valid? The Server needs to register itself with the control system name server. If it can’t speak IP correctly then this is impossible.
If a DOS or WINDOWS server does not have the IP stack loaded, then it must have the IPX stack loaded and declare that it doesn’t speak IP by setting the environment variable TCP = NONE.
- Are the IP gateway and net mask valid? See comments above.
- Is there a route from your server to the name server? (This is relevant to VxWorks servers which neet to “AddRoute” at boot time).
- Get the IP address of the equipment name server (ENS). You can look at the file cshosts.csv to see what its IP address is. This file should be located where your TINE_HOME environment variable points (or in the same directory as the server if the environment variable is not set). Try a ping from your server to the name server to see if you can reach it. It you can’t then solve that problem first before looking any farther.
2). Check your server environment
- Have you set the environment variables FEC_HOME and TINE_HOME? Likely, TINE_HOME has been set administratively for you. Check these settings and see where they point to.
For a server, TINE_HOME is relevant since, a server is briefly a client to the equipment name server, and needs to be able to resolve the address of the name server.
- In the TINE_HOME directory, you should see the file cshosts.csv. This file must be present in order to resolve the name server address.
- In the FEC_HOME directory, you should see your fecid.csv file, and your exports.csv file.
If these files are not present, then you must do all your name registration dynamically in code (did you do this?). Most likely, you are using the fecid.csv file. Windows servers usually do not use the exports.csv file – so make sure in this case you have set the ExportName property of the srv.ocx control to some system-wide unique name and that the EqpName property of the srv.ocx is also set to a non-zero length string. Note that the legacy environment variable FECDB will be used in lieu of FEC_HOME, if FEC_HOME is not set. Likewise CONTROLDB will be used in lieu of TINE_HOME if TINE_HOME is not set.
3). Is the server running?
- Check the process list to make sure the server is really running.
- Check in debug mode if the server runs through its initialization task correctly. Make sure you check all the return codes to see if all initialization steps were successful.
- In Windows servers, you should enable the control only after the EqpName and ExportName properties have been set (usually at design time) and before any call to RegisterProperty().
- Check the server log file. This is called fec.log and is located in the working directory for console server applications or in the FEC_HOME directory for windows GUI server applications. If something went wrong, it should be indicated inside this file.
It is normal to see entries in the log file indicating that certain files were not found (such as users.csv, etc.). Some files only have a relevance to certain features and their absence would not hinder operation (see the discussion on .CSV files).
4). Is the client up to date?
- If you’ve checks steps 1), 2), and 3) and everything seems alright, then it could be that you simple need to force a reload of the database information on the client side.
This is particularly true if you are trying to see a brand new server. Either restart your client process, or if using the “Instant Client” in Windows, select the “Reload” option from the Options menu, and see if the problem goes away. If the address of the server has changed since the last successful start, you might need to select “Flush address cache” from the options menu.
My 16-bit Windows Server has a General Protection Fault!
1) Check the obvious
- Make sure all Visual Basic arrays you pass to the winsrv.vbx (via CADDR()) are large enough to hold the data your RegisterProperty() routine has claimed they are.
- Check to make sure the Visual Basic arrays you pass to winsrv.vbx have the format you said they do in the RegisterProperty() routine.
2) Check your windows environment
- Is there a daemon application which loads the winsrv.dll at Windows initialization time?
This is the healthiest state of affairs, since you can then start and stop server applications at will.
- Are there more than one Windows applications which are using the winsrv.vbx server component?
If yes, and there is no daemon, then the order in which these applications are started and stopped is important. Since system resources are “owned” by the first application to load the winsrv.dll. If this application disappears, then all others using the same dll will immediately experience difficulties. These comment also apply to the same application running as a standalone application and in Visual Basic. Make sure the applications are stopped in reverse order as they were started.
My Server says “Bind: Address already in Use” and then stops!
1) If you are running DOS or 16-bit Windows:
- Reboot your machine. This could only arise from a previous system crash that did not release the IP resources.
2) If you are running VxWorks:
- You have attempted to spawn the RPCServer task more than once. In VxWorks, you only f * need (and can only have) one RPCServer task running on the CPU.
3) If you are running UNIX, VMS, or 32-bit Windows:
- This indicates that there is already at least one server process running on the machine.
This is allowed, as on these platforms the individual server processes run in their own address spaces. However, only one process can listen on a particular server port.
Therefore you need to pay attention to the Port Offset parameter (see the API section for your platform). You should find out which other server processes are running on your machine and what port offsets they use and then choose and implement a unique offset for your server. Once you decide on your server’s port offset, stay with it, as the clients which communicate with your server will also use it.
My Win32 Server seems to send corrupt data every now and then!
1) Is the array you are passing to the EqpSendData() method okay? This array is of course the source of data you are transferring, so make sure the problem is not here.
2) Make sure you only call the method EqpSetCompletion() (or set the EqpStatus property) once while inside the EqpFcn() event. This is very important as ActiveX events do not support return codes. Calling the EqpSetCompletion() method is thus a signal that the event has been processed, at least as regards data retrieval and transmission. Note that some containers, such as LabView cache the incoming event and return immediately.
Also, if you make use of DoEvents() inside the event in Visual Basic, you also return control to the underlying server DLL and Srv.ocx. The point to remember is that the ActiveX control (Srv.ocx) maintains an event queue and only knows where to move the queue head and tail according to the firing of the event and the call to EqpSetCompletion(). The EqpStatus property is deprecated and is only there for backward compatibility when converting Visual Basic 3.0 applications to Visual Basic 6.0 applications. Nonetheless, if EqpStatus is used, it serves the same purpose as the EqpSetCompletion() method call. Namely, it advances the tail pointer in the event queue, so only one of either EqpSetCompletion() or EqpStatus should be used.
Using both of these, or otherwise calling EqpSetCompletion() more than once within an event is the most common cause for ‘corrupt’ data being sent.
3) Make sure that EqpSetCompletion() is called after the EqpSendData() method (or EqpSendDataEx()) has been called. As Visual Basic does not cache events, you could call EqpSetCompletion() first in VB as long as there is no DoEvents between the call and EqpSendData(). However it is better to avoid doing this.
I can’t seem to transfer any more than 64 Kbytes of data. I thought it was possible to send more.
1) You will need to set the value of MaxRPCTransportSize to the corresponding value of the largest request you want to support. This variable has a default value of 64 Kbytes for most platforms (32 Kbytes for DOS). As calls are double buffered to the extent that one primary working area is allocated once upon startup (and is used as a dynamic repository for outgoing control data) while a data link will itself cause a reference repository to be allocated, you have control over how large a call can be (within the constraints of the available memory). So if you want to support a call for 1 Mbyte of data you should set MaxRPCTransportSize to 1000000 prior to system initialization.
Note that this will have to come out of main memory! A DOS server will of course not trivially be able to support such large calls. On the other hand, if you know that no call will ever exceed say 4 Kbytes for instance, you can also set MaxRPCTransportSize to 4000 and save on the available heap, which is something that is sometimes necessary for DOS servers due to the 640 Kbyte limit.
I can’t seem to transfer data any faster than at 1 Hz. I thought it was possible to send data at a faster rate.
1) You will need to set the value of MinPollingRate to the minimal value in milliseconds which want to allow. This variable has a default value of 1000 milliseconds on some platforms and serves to protect servers from inadvertent fast data access which would serve no purpose but to make the server busy. There are however frequently cases where a fast data access is desirable, and you should set this value accordingly. The absolute minimum value is 20 milliseconds (50 Hz). An attempt to set this to a value smaller than 20 will ultimately be overridden.