PxPlus User Forum

Twitter Twitter Twitter

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Messages - Mike King

Pages: [1] 2 3 ... 60
Programming / Re: Reading simple data from a TCP channel
« on: March 23, 2023, 02:44:00 PM »
Yes -- since its a streaming interface and since TCP/IP itself breaks up transmissions then reassembles them when they are received there is never a 100% clean way to assure you got all the data unless you issue something like a READ RECORD (nn, SIZ=xx) R$ where you know you are expecting fixed size data chunks.

BTW: If you notice on the last PNG you posted the time stamp for the split transmission was identical.  Basically something in the TCP/IP protocol simply caused the blocks of data to arrive independently thus part of the transmission was received and passed to your program with the remainder arriving probably milliseconds later. 

This streaming of TCP data is generally why TCP transmissions normally are designed to provide length information (e.g. the Content-Length header on web requests) or have a signal (e.g. the empty line between web page headers and contents) that can be used to detected end of transmission.

Programming / Re: Reading simple data from a TCP channel
« on: March 23, 2023, 01:55:10 PM »
Yes but TCP is a streaming transmission so arrival times are never assured.  A transmission error somewhere along the stream can cause a delay/small packet at any time.

Also, if you receiving small intermittent packets I would suggest you add the option NODELAY to disable the Nagles algorithm on the connection, it is normally enabled on TCP. (See Nagles Algorithm at https://en.wikipedia.org/wiki/Nagle%27s_algorithm).  It also possible the sender may need to disable the algorithm to provide an even flow of data.

All that being said, did the example I posted with the trailing comma resolve what you seeing?

Programming / Re: Reading simple data from a TCP channel
« on: March 23, 2023, 01:44:52 PM »
You have specified a blocking factor of 4K so every time you read the most you will get back is 4K regardless of how much has been received.

Your PRINT command will then insert a visible line break on the output -- the line feed is not in the data but simply a result of the PRINT statement not having a trailing comma..


Code: [Select]
  let TCP=unt; open (TCP,bsz=4096,err=ERR_PORT)"[tcp];9004;KEEPALIVE"
  read record (TCP,err=ERR_READ)A$
  print A$,
  goto READ_NEXT

Programming / Re: REMOVE failing if record not EXTRACTed
« on: March 21, 2023, 02:59:56 PM »
You might want to submit this to our helpdesk so someone in support can have a look at it.

They would probably need the type of error you are getting (error code/message) the file definition from FIN(nnn, "FILE_CREATE"), and what the key was you used and how you created it.

Programming / Re: Linux User Help
« on: March 20, 2023, 07:43:15 PM »
If all you want to do is have all *plus/cs/host clients run under a single, common non-root userid then you could either use the Linux 'su' command to change the userid for the command that started *plus/cs/host or you might even be able to write a small program that does a DEF UID prior to running *plus/cs/host and launch that instead.

Programming / Re: Linux User Help
« on: March 20, 2023, 01:40:42 PM »
There are a couple of ways to address this.

If  you are using the Simple CS program for your connections launch the Simple CS Host program on the desired user.  This will result in all the spawned processes using that user id.  There is however a slight caveat and that is most Linux distributions will not allow any process other than those running as 'root' to monitor any well-known port number (that is ports under 1024).  Now generally this will be fine for the CS host program as its default if 4093 but if you are using a lower port number you may have to change.

If you want different processes to run on different user-ids then in your application, once you know what user-id you want to use you can issue a DEF UID=xxx (and optionally DEF GID=xxx) in order to change the user-id that the processes run on.

Another option is to simply have your users use WindX to directly sign-on to the Linux server and have a .profile (or .bash_profile) in their starting directory that launches PxPlus.  This will have the users maintain their user-id and security settings.  If your application needs to spawn additional WindX processes, you simply need to set the global variable %PXPLUS_HOST to "*hostaddr;port" where hostaddr is the Host Linux servers address as seen by the workstations, and port is the port number to use.  (See the note at the bottom of  https://manual.pvxplus.com/page/windx/windxutl.htm  for details).

Programming / Re: Assign a query to a cell at run time.
« on: March 17, 2023, 10:51:37 AM »
Technically the Query property doesn't exist (at least in Nomads -- in iNomads there is a property called CellQuery$ which you can alter dynamically).  What Nomads does is maintain internal tables relative to the grid column/row with the query setting.

There really isn't a way to dynamically change this table but what we would suggest is assign a query that runs a program and in that program you can decide which actual query you want to run and should your logic decide there isn't a query, display an error message.

iNomads / Re: Apache 32/64
« on: March 13, 2023, 03:52:25 PM »
That note applies to the fact that on Windows we ONLY compile and provide a 32 Bit mod_inomads.so for Apache 2.2 and 2.4.  You can safely recompile the mod_inomads module yourself as we provide the source however you will require a 'C' compiler and to download the Apache development source headers for Windows.

For Linux, Aix, Unix, and MacOS you would compile the source based on the OS and hardware you are running on using the OS supplied 'C' compilers using the apxs command that comes with Apache.

Note you can mix 32 and 64 bit Apache and PxPlus (i.e. You can use the 32 bit Apache with either the 32 or 64 bit PxPlus on Windows).

Programming / Re: Strange if then else behavior
« on: March 09, 2023, 09:48:20 AM »

Yes the line numbers are assigned so you can edit at command mode if needed when running in text mode.  Mind you with PxPlus 2023 due in May you should be able to run EZWeb on a Linux/MacOS/AIX box then use ED+ to edit your programs graphically from any browser.


When looking for the closing bracket the system has to scan ahead through the code, this is due to the interpretative nature of the language and that you can alter code at run time.  Given this, from a performance perspective it is better to keep the directives on one line as scanning will be faster. 

Also, as mentioned earlier, I generally prefer moving multiple lines to smaller subroutines.  A GOSUB takes very little time and will often run faster than scanning looking for brackets.  I also find it has the advantage that if I need to insert additional lines into an IF condition having them in a subroutine makes that easier especially when they are sub-ordinate IF directives. I find it also helpful if the subroutine name provides a 'clue' as to what the logic is doing.

For Example:

    IF QtyOnHand <= 0
      GOSUB BackOrder
      GOSUB CommitInventory

I have seen far too many programs not work because someone inserted or changed a few lines of code in between curly brackets that they didn't realize were present.  By avoiding curly brackets and using *IT or ED+ to format your code I find it makes it more readable and supportable.  I almost never use curly brackets (but maybe I'm just a bit weird in that respect).

Programming / Re: Strange if then else behavior
« on: March 08, 2023, 11:08:52 PM »
Add a comma after the label to start the list from there.  Without a trailing comma you will only get one line.

Programming / Re: Strange if then else behavior
« on: March 08, 2023, 05:28:41 PM »
Quick follow up:

To give you an idea of how my coding style looks have a look at *plus/inomads/inomads around the label Set_Userid:

If you load this program and do a standard LIST EDIT SET_USERID (or call the program up in the *it or *ed+ editors with Formatted output enabled) you will get something like this:

  IF NOT(%inomads'ForceLogon) AND %inomads'LogonReqd$<>"Y" \
   THEN %inomads'Userid$=NID;
  DEF UID="*Void*" LOCAL
  CALL "*secure","F:LOGIN"
  DEF UID="*"
  IF %inomads'Userid$="" \
   THEN objsec=NEW("*secure");
        IF objsec'unsecured \
         THEN MSGBOX "System security is not enabled but required for this transaction","Error","STOP";
              EXITTO SKIP_TX \
  IF %inomads'use_signon_uid \
   THEN GOSUB Linux_signon WITH reqd_uid$=%inomads'Userid$

Which I find fairly easy to read and follow. 

Now some of the lines if you list them un-formatted are quite long, with edited listing enabled the built in code formatting makes following the logic quite easy -- and in my opinion much easier than coding a bunch of brackets. 

Programming / Re: Strange if then else behavior
« on: March 08, 2023, 05:13:16 PM »
The issue is a result of the line oriented nature of the language.  IF ... THEN ... ELSE ... will basically process what is on the line.

To span multiple lines then the THEN or the ELSE *MUST* be immediately followed by the OPEN bracket otherwise the conditional processing ends.

What was happening is that when the system saw your ELSE IF MIKE$=... because the ELSE was not followed by a curly bracket the IF directive was now fully complete thus the next line was executed.

Personally I try to avoid curly brackets as they make lines hard to read.  I would enable formatted output in *IT and code the line as:

0005  mike$="P"
0010  IF mike$="P" \
        THEN PRINT "Yes P" \
        ELSE IF mike$="T" \
              THEN PRINT "Doing T too"
0020 !

Its just easier to read.

And where there are more than three lines in any of the of the IF blocks I usually put the code into a GOSUB with a label to make the code more readable.  For example in instead of just PRINT "Yes P" you had 10 lines of code to execute I'd put that in a GOSUB called something like Mike_Code_P.  (My $0.02)

Language / Re: *X Mnemonic / Print Channel Timing Question
« on: March 07, 2023, 04:18:52 PM »

No, you can safely close the file in your *X logic.  The system checks for this and handles it appropriately. 

ODBC / Re: ODBC Date Issue
« on: March 03, 2023, 02:34:25 PM »

A couple of things you might try (and why I am suggesting them):

1) If there is no WHERE clause does it return all the orders.  (Checking all records accessible and none have invalid data/keys)

2) Do you have a key on the file based on the date and is it Ascending or Descending? (Perhaps the driver is using an alternate key to access the file and the definition/data is out of sequence)

3) If you add an ORDER BY on the ORDER_NUMBER does the query work? (Try to force the system to use the primary key)

4) What is the CLASS for the Date field in the PxPlus Data Dictionary? (could the class name be incorrect given the data in the record -- if record has dates stored as MMDDYY then the class should be DATE-MMDDYY.

Web Services / Re: *web/email question regarding running in background
« on: March 03, 2023, 10:26:01 AM »
Some Email servers simply don't respond to invalid credentials and let the caller timeout eventually.  They do this to prevent spammers from trying to hack onto your email server by constantly trying invalid credentials. 

For example if you take our email server, if you fail the connection too many times it blocks your IP for about 10 minutes, and if this occurs more more than once or twice it will block your IP for a few days. 

When the IP is blocked the email program will get no response for a connection and thus hang for a while until the connect times out.

Pages: [1] 2 3 ... 60