Cache' TCP/IP communication help needed.

72 views
Skip to first unread message

Kevin Toppenberg

unread,
Jun 2, 2012, 9:29:34 PM6/2/12
to hard...@googlegroups.com
I am having some difficulty with TCP communications with Cache' involving buffers.

Goal: communication between mumps client on computer #1 <---> java server on computer #2

First I got communication working between two java processes on the two computers, using sample code found here:
http://systembash.com/content/a-simple-java-tcp-server-and-tcp-client/

I next wrote mumps code to talk to the same java server code based on above

TESTTCP ;       
        NEW IP SET IP="192.168.1.123"
        NEW PORT SET PORT="6789"
        NEW TIMEOUT SET TIMEOUT=10
        DO CALL^%ZISTCP(IP,PORT,TIMEOUT)
        IF POP QUIT
        ;"------- Send out query -------------
        NEW I FOR I=1:1:5 DO
        . WRITE I," HELLO",$CHAR(13,10)
        WRITE "#DONE#",$CHAR(13,10)
        ;"------- Start looking for reply -------------
        NEW DONE SET DONE=0
        FOR  DO  QUIT:DONE
        . READ IN:2
        . IF IN="#BYE" SET DONE=1
        ;"------- Finished -------------
        DO CLOSE^%ZISTCP
        QUIT
       ;

The first part of this works, of sorts.  The mumps code sends out the 5 "HELLO"'s and the "#DONE#", but the text seems to be stuck in a mump/Cache' buffer.  It is not until the CLOSE^%ZISTCP is called that the server actually gets the text from the client.  And then all at once.  I can run the server code and look at what it is getting line by line.  It establishes communication with the client, and then hangs at the line:
  clientSentence = inFromClient.readLine();

But as soon as the mumps process closes the channel, suddenly the server gets everything.

I should say, that it was working before I put in the bit of code about looking for the reply (with READ statements)

Normally I wouldn't care about this.  But I want my mumps program to send out a query, and then get back a reply from the server.  What is happening in the code above is that mumps code hangs at the READ part.  It doesn't get anything back from the server, because the server hasn't gotten anything from the client yet (it's still in the buffer).

So is there a way to force a flush of the buffer?

Is there a better way to do this?

Thanks
Kevin

Sam Habiel

unread,
Jun 3, 2012, 1:18:08 AM6/3/12
to hard...@googlegroups.com
Kevin... too sleepy now...

Briefly,

! is the buffer flush in Cache. The non portable one is W *-3. You can
use either one.

GT.M uses both ! or # depending on your socket parameters...

Look at XWBRW in VISTA or FOIA RPMS; also you can look at BMXMON in
the trac repo (my refactored code from the original BMXMON in RPMS).
First few lines tell you that I replaced all W *-3 to make it work on
GT.M.

https://trac.opensourcevista.net/svn/BMXNET_RPMS_dotNET_UTILITIES-BMX/branch/BMX41000/routines/BMXMON.m

Sam
> --
> http://groups.google.com/group/Hardhats
> To unsubscribe, send email to Hardhats+u...@googlegroups.com

John McCormack

unread,
Jun 3, 2012, 1:44:44 AM6/3/12
to hard...@googlegroups.com
Or use variable IOF setup by ZISTCP when you want to send your data on it's way, i.e. W @IOF.

VAR(%IO) ;Setup IO variables
         S:'$D(IO(0)) IO(0)=$I
         S IO=%IO,IO(1,IO)=$G(IP),POP=0
         ;Set IOF to the normal buffer flush. W @IOF.
         S IOT="TCP",IOST="P-TCP",IOST(0)=0
         S IOF=$$FLUSHCHR
         Q
         ...
         ;
FLUSHCHR() ;Return the value to write @ of to flush the TCP buffer
         N OS S OS=$P(^%ZOSF("OS"),"^")
         Q $S(OS["GT.M":"#",1:"!")

Kevin Toppenberg

unread,
Jun 3, 2012, 4:39:35 PM6/3/12
to hard...@googlegroups.com
John and Sam,

Thanks for your replies.

I like the idea that IOF contains the character needed to flush the buffer.  When I run my code on Cache', it comes back with IOF="!"

I am confused why I need to write @IOF instead of IOF.  Doesn't @ act like dereferencing a pointer?  I.e. if REF="^TMP(1)" then WRITE @REF would give the contents of @REF.  But what does @"!" mean?  I initially thought that this was a typo on John's part. But W @IOF works, and @ IOF does not.  So he was right.

Sam was also correct that W *-3 works, but I want to keep my code portable, so will use the @IOF.
Sam, when you said that ! will flush the buffer, do you mean that

  W "HELLO",!  <--- this ! will flush the buffer?  It doesn't seem to do it.

As it is, in order to get the java process to recognize the end of line, I have to use
   WRITE I," HELLO",$CHAR(13,10)
instead of
  WRITE I," HELLO",!

Thanks
Kevin

Sam

On Sat, Jun 2, 2012 at 6:29 PM, Kevin Toppenberg <> wrote:
To unsubscribe, send email to Hardhats+unsubscribe@googlegroups.com

    

Kevin Toppenberg

unread,
Jun 3, 2012, 5:12:30 PM6/3/12
to hard...@googlegroups.com
OK.  The buffers seem to be working OK.

Now I am am having trouble with reading back in.

I looked at XWBRW and it seems to be reading in characters at at time.  I want to read in LINES at a time.

So I need to know what the line terminators are.  And I want this all in portable code.

From the java, I tried sending a series of strings with a "\n", $CHAR(10) as a line terminator.  And then on a different run, a "\r",  $CHAR(13), as the line terminator.  In both cases, my line of mumps code:
  READ IN:2

I find that variable IN is filled with all the text at once, e.g.
  "test"_$c(10)_"test2"_$c(10)_"test3"_$c(10)
or
  "test"_$c(13)_"test2"_$c(13)_"test3"_$c(13)

As I have written this, it occurs to me that the channel is probably being opened in a binary mode, i.e. the user may want to receive the line feed characters back instead of them being used as line terminators.  Is this true?  If so, then I will need to write a Readln() type function that divides up the input myself.

Dang it's hard being ignorant!

Kevin

DanB

unread,
Jun 3, 2012, 5:17:24 PM6/3/12
to Hardhats
W IOF prints the literal value of the variable IOF (W "!"), whereas W
@IOF gets the value of IOF and then executes the WRITE command with
that value (W !)

not sure if its the best example, but something like this:
CPM,ROU>>S X="Y" S Y="HI"

CPM,ROU>>W X
Y
CPM,ROU>>W @X
HI
> >          *;Set IOF to the normal buffer flush. W @IOF.*
> >          S IOT="TCP",IOST="P-TCP",IOST(0)=0
> >          S IOF=*$$FLUSHCHR*
> >          Q
> >          ...
> >          ;
> > *FLUSHCHR() ;Return the value to write @ of to flush the TCP buffer*
> >          N OS S OS=$P(^%ZOSF("OS"),"^")
> >          Q $S(OS["GT.M":"#",1:"!")
>
> > On 6/3/2012 12:18 AM, Sam Habiel wrote:
>
> > Kevin... too sleepy now...
>
> > Briefly,
>
> > ! is the buffer flush in Cache. The non portable one is W *-3. You can
> > use either one.
>
> > GT.M uses both ! or # depending on your socket parameters...
>
> > Look at XWBRW in VISTA or FOIA RPMS; also you can look at BMXMON in
> > the trac repo (my refactored code from the original BMXMON in RPMS).
> > First few lines tell you that I replaced all W *-3 to make it work on
> > GT.M.
> >https://trac.opensourcevista.net/svn/BMXNET_RPMS_dotNET_UTILITIES-BMX...
> > --http://groups.google.com/group/Hardhats
> > To unsubscribe, send email to Hardhats+u...@googlegroups.com

John McCormack

unread,
Jun 3, 2012, 8:53:10 PM6/3/12
to hard...@googlegroups.com
Along Dan's reply. IOF is the variable that hold the code to perform a "form feed" or "top of form" function on the device.

STANDARD DATA DICTIONARY #3.2 -- TERMINAL TYPE FILE                                                     JUN 3,2012@19:22:57  PAGE 1
STORED IN ^%ZIS(2,  (188 ENTRIES)   SITE: Vista-Office EHR   UCI: WVDEV,WVDEV                                      (VERSION 8.0)
 
DATA          NAME                  GLOBAL        DATA
ELEMENT       TITLE                 LOCATION      TYPE
-----------------------------------------------------------------------------------------------------------------------------------
 
3.2,2         FORM FEED              1;2 FREE TEXT (Required)
 
              INPUT TRANSFORM:  D CHECK^%ZISS1,FORM^%ZISS1 K:$L(X)>70!($L(X)<1) X
              HELP-PROMPT:      ARGUMENT OF MUMPS 'WRITE' TO CLEAR SCREEN OR GO TO TOP-OF-PAGE
              DESCRIPTION:      The argument of a MUMPS WRITE statement that will set the top-of-form for the use of tractor-feed
                                paper on a printer, or will clear the screen of a video display terminal.

NAME                            FORM FEED
------------------------------------------------------------------------------------------------------------------------------------
 
C-3101                          #,$C(27,76)
C-ADDS                          #
C-ADM3                          #,$C(26)
C-DATAMEDIA                     #
C-DATATREE                      #
C-DEC                           $C(27)_"[2J"_$C(27)_"[24A"_$C(27)_"[80D",#
C-DEC132                        $C(27)_"[2J"_$C(27)_"[24A"_$C(27)_"[80D",#
C-FALCO                         #,$C(27)_"~*"
C-H1500                         #,$C(126,28)
C-HINQLINK                      #,$C(27,91,50,74,27,91,72)
C-HP110                         #,$C(27,72,27,74)
C-HP2621                        #,$C(27,72,27,74)

S IOF="#,$C(27,72,27,74)"
 
W IOF
#,$C(27,72,27,74)

You want the code in IOF to be resolved, not printed as a literal string. In this case besides the "#" you want MUMPS to send the ASCII code represented by the characters 27,72,27, and 74 to the device.


The "!" is not sent to the external system. It's the signal (command) to the MUMPS interpreter to send whatever characters have accumulated in the output buffer. That's how MUMPS interfaces to a TCP/IP (network) connection. When it encounters the flush command it takes the data in the buffer and sends it out the connection. TCP/IP then puts it into a packet(s) on the network based on the packet size specified for your system. Otherwise you could be sending out hundreds of TCP/IP packets each with one character which would be very inefficient.

You probably need to
WRITE I," HELLO",$CHAR(13,10),@IOF  - the IOF tells MUMPS to flush the characters from the buffer and send out the wire.

Chris

unread,
Jun 3, 2012, 8:57:25 PM6/3/12
to hard...@googlegroups.com
... it occurs to me that the channel is probably being opened in a binary mode ... is this true?
  • No it is not true. I'm going to guess your basing what you describe based on FTP experiences; if true those experiences do not apply. There is no such thing as opening a socket in ASCII or BINARY mode. FTP does support the transfer of files using ASCII or BINARY mode but that is a FTP implementation and not a socket specification.
  • When you program at the socket level it is up to the programmer to use a OSI Layer 7 (also known as application) protocol or make up a new protocol. An example of an existing layer 7 protocol is FTP, DNS, SMTP, NTP, LDAP. All of which are defined by RFCs. You can google "rfc ftp" for all FTP TCP implementation details.
    • When you create a new protocol it is up to the programmer to define how messages being sent are structured and how messages being received are parsed.
  • TCP only provides a mechanism for reliable transmission of data between two endpoints.

Aylesworth, Marc CTR USAF AFMC AFRL/RISA

unread,
Jun 4, 2012, 8:40:25 AM6/4/12
to hard...@googlegroups.com
Java uses Unicode, which is 2 bytes long Mumps uses one byte ASCII or utf-8 . I would bet if you tested on the linefeed for Unicode or did a conversion it might work. It may also be looking at the wrong byte, maybe a shift.
 
Marc Aylesworth
 
RRC C3I Group
525 Brooks Road
Rome, NY 13440
 
 


From: Kevin Toppenberg
Sent: Sun 6/3/2012 5:12 PM
To: hard...@googlegroups.com
Subject: [Hardhats] Re: Cache' TCP/IP communication help needed.

--

Bhaskar, K.S

unread,
Jun 5, 2012, 10:42:43 AM6/5/12
to hard...@googlegroups.com


On 06/03/2012 08:57 PM, Chris wrote:
... it occurs to me that the channel is probably being opened in a binary mode ... is this true?
  • No it is not true. I'm going to guess your basing what you describe based on FTP experiences; if true those experiences do not apply. There is no such thing as opening a socket in ASCII or BINARY mode. FTP does support the transfer of files using ASCII or BINARY mode but that is a FTP implementation and not a socket specification.
  • When you program at the socket level it is up to the programmer to use a OSI Layer 7 (also known as application) protocol or make up a new protocol. An example of an existing layer 7 protocol is FTP, DNS, SMTP, NTP, LDAP. All of which are defined by RFCs. You can google "rfc ftp" for all FTP TCP implementation details.
    • When you create a new protocol it is up to the programmer to define how messages being sent are structured and how messages being received are parsed.
  • TCP only provides a mechanism for reliable transmission of data between two endpoints.

[KSB] To elaborate, reliable, serial transmission of octets (8-bit bytes) between two endpoints.  No interpretation of the octets, no time guarantees, no line breaks, no assurance of what octet travels in the same packet as what and by what route, etc.

Regards
-- Bhaskar



-- 
GT.M - Rock solid. Lightning fast. Secure. No compromises.
_____________
The information contained in this message is proprietary and/or confidential. If you are not the intended recipient, please: (i) delete the message and all copies; (ii) do not disclose, distribute or use the message in any manner; and (iii) notify the sender immediately. In addition, please be aware that any message addressed to our domain is subject to archiving and review by persons other than the intended recipient. Thank you.
Reply all
Reply to author
Forward
0 new messages