TweetFollow Us on Twitter

Networking HC
Volume Number:5
Issue Number:12
Column Tag:HyperChat™

Related Info: AppleTalk Mgr

A Look Into Networking

By Donald Koscheka, Ernst & Young, MacTutor Contributing Editor

Note: Source code files accompanying article are located on MacTech CD-ROM or source code disks.

Programming the Network

Network programming is fun. Over the past year, I’ve presented a suite of XCMDs that provide the Hypercard developer with network access. Rather than present a new XCMD this month, I thought it might be interesting to revisit some of the xcmds that we developed during the year. If you don’t have access to back issues of Mactutor, you can obtain the source code for these xcmds from this magazine.

Programming the network is not unlike programming in Hypertalk. In both instances, you are concerned with the behavior of distributed processes. In HyperTalk, processes are distributed over several card and background objects. On the network, objects are distributed over time.

Time distribution of processes adds a new wrinkle to the programming task: how do you know when a given process has completed? The problem stems from the fact that we operate the network asynchronously; when we issue a request for some network service, we don’t wait around for an answer. Rather, we return to Hypercard, leaving the network to handle the request in its own good time.

Figure 1 depicts a card for a prototypical network application called Hyperserver. The card contains two icons, each of which provides some access to the network. Clicking on the volumes icon will cause the card to display a list of available servers. Selecting one of these servers will immediately send a message to the selected server requesting a list of its mounted volumes. Similarly, the catalog icon will return a catalog of the current folder on the server (for now, I leave it to your imagination to determine what other things one can do with such a card).

Figure 1. A prototypical screen for HyperServer

The process of sending a message to a server requires that you first call the call the server. Next you send a “get volumes” message to the server. Then you must wait for a response from the server. Once the server responds, you hangup).

Waiting for some input before advancing to the next stage suggests a state machine. Figure 2 depicts just such a state machine. Each circle in the diagram is a state. The double circles are termini. They start or begin a process. The arrows are state transitions, their labels tell us what stimulus will force a transition to the next state. The looping arrows in the diagram suggest the concept of waiting. For example, when a call request is made, you can’t immediately start talking, you have to wait for the other party to answer first. The process of answering the call triggers a transition to the connected state. Once connected, requests can be made to the server. Since requests imply a response, this state needs to wait for input before moving on. The process of receiving an answer to the request will trigger a transition to the next state (handle response). Once the request is serviced, we can go back to the connected state where we either wait for input and send another request (or hang up if that’s appropriate).

State transitions can occur in response to one of two classes of stimuli: external or internal. External stimuli comprise information coming in over the “wire”. Examples of external stimuli include service requests to a server and responses coming from a server. In figure 2, we model the external stimuli as the Service state and the Handle State. The handle state accepts the input from the remote end as a response to some previous request issued in the send state. For this reason, you should never get to the handle state unless you first pass through the send state.

The respond state in Figure 2 can only be reached from the service state. That is, you can only respond to a stimuli given that a request for service was made from a remote end. (For readability, not all states are depicted in the figure).

Figure 2 The State Machine For HyperServer

Internal stimuli are called requests. Requests are messages that are sent to a server. Once a request is issued, we must wait for a response. For example, calling is an example of a message that request a connection with the server.

Once the server answers the call, we can move to the connect state. The connect state is implemented in the idle method of the stack method in listing 1. In addition to listening for external stimuli via ADSPListen, the idle method also manages the request mechanism.

We synchronize requests using a simple queue. Requests get added to the end of the queue and get serviced from the start of the queue. The queue is stored in the global container “message_queue”. Each line in message_queue corresponds to a message. The first line in message_queue is the next message to service (not the current message). To execute a message, we first move it into the “message_pending” container. Every other element in the queue then moves up in the line.

The message_pending item will be executed on the next activation of the idle method. If a message is sent that requires some external response, it should be followed by a “PENDING” message. Pending does nothing which is why it’s useful as a blocking mechanism. The only way for the queue to advance is to have some method activate the NextMessage method. So PENDING will remain the current message in the queue until some external stimulus unblocks it.

For example, to issue a call to a remote called “Allen” you might execute something to the effect of:

AddMessage “Call”&quote&”Allen”&quote
AddMessage “PENDING”

On the next pass through the idle method, the Call message will be executed invoking the call method in the script. The call method dials up the remote end and activates nextMessage which advance the queue to the next message, in this case the current message becomes “PENDING”.

The queue cannot be unblocked until the server answers the call or the call times out. When the call is answered (in ADSPListen), the connectionMade method is activated unblocking the “PENDING” message.

Some messages have don’t care results. When we hangup on a remote end, we generally don’t care to wait around to see if the other guy hung up. Thus the HangUp message is not followed by a pending message.

As a rule, if you have a message that issues a request, you must follow the message with a “PENDING” message will tells the state machine to wait for an external stimulus before proceeding.

Listing 1 is the stack script that implements this state machine plus the response handlers (not shown in Fig. 1). Before running the state machine, we install HyperADSP in the openstack method. Similarly, we shut down HyperADSP in the closestack method.

Think of the idle method as implementing the connect state and the rest of the script should be a little easier to read. For brevity, I’ve left out the methods that originate the requests, but they’re easy enough to reconstruct (or get a copy of this month’s disk for a demo).

-----------------------------------------------
-- Following are the stack methods for opening
-- closing and listening for traffic on the
-- network
--
-- Due to space limitations, this stack is not
-- complete.  This month’s source disk contains 
-- a complete demo of this stack.
-----------------------------------------------

on openstack
  global globalADSPData, globalSKTData, globalNBPData, myEntityName
  global HyperADSPData, adspcaller, LookupTable
  global message_queue, message_pending
  
  set the cursor to 4
  put empty into card field “current Server”
  put empty into card field “Subscribers”
  put empty into card field “Current Pathname”
  put empty into card field “Current Catalog”
  put empty into card field “log”
  
  put empty into message_pending
  put empty into message_queue
  
  if globaladspdata is empty then
    set the cursor to arrow
    adspinstall
    if the result is not empty then
      put the result
    else
      nbpOpen
      if the result is not empty then
        answer the result with “OK”
      else
        nbpRegisterName “”, “HyperServer”
        log “Welcome to HyperADSP!”
      end if
    end if
  else
    log “HyperADSP already open!”
  end if
end openstack

on idle
  global message_pending
  
  --
  -- if no message is pending, get one from the queue
  -- if the queue is empty, do nothing
  --
  
  if message_pending is empty then NextMessage
  
  if message_pending is not empty then
    send message_pending
  end if
  
  adspListen “getTheMessage”
  pass idle
end idle

on getTheMessage
  global hyperadspdata, adspcaller, message_pending, incoming
  
  set cursor to 4
  set lockscreen to true
  
  put hyperadspdata into incoming
  
  get line 1 of incoming
  --
  -- Notice how we “turn the messages around” here.
  -- a put message tells us to take the incoming data
  -- a get message tells us to handle an incoming request
  
  if word 1 of it is “put” then Receive incoming
  if word 1 of it is “get” then Handle incoming
  
  set lockscreen to false
  set cursor to arrow
end gettheMessage

on closeStack
  adspRemove
  if the result is not empty then
    answer the result with “OK”
  else
    nbpClose
  end if
end closestack

----------------------------------------------
-- Network Callback methods.
--
-- These methods are executed in response to
-- some activity on the network
--
-- connectionMade : answer an incoming call
-- doALookup:  Update the names table
----------------------------------------------

on connectionMade
  global adspcaller
  
  if adspcaller is not empty then
    
    -- now that the connection is made, we can dismiss the calling
    -- message from the queue:
    Log “Connect to:”&&adspcaller
    put empty into adspcaller
    
    NextMessage
  end if
  
end connectionMade

on DoALookup
  -----------------------------------------------
  --
  -- DoALookup returns a list of names along with
  -- their registered  types.  There is a catch
  -- that we need to handle: If we want to display
  --the name without the type, we need to delete
  -- the last item in the line.
  --
  -- For example:
  --  Koscheka, Don, HyperServer
  -- needs to be reported as:
  --  Koscheka, Don.
  --
  -- Note that asking for item1 of the line won’t
  -- do since the comma is part of the registered
  -- name.
  --
  -----------------------------------------------
  
  global lookupTable, currentZone
  
  set the cursor to 4
  put GetZoneInfo( TRUE ) into currentZone
  
  put nbplookupnames( “HyperServer”, currentZone ) into lookupTable
  
  repeat with i = 1 to the number of lines in lookupTable
    get the number of items in line i of lookupTable
    put empty into item it of line i of lookupTable
    get the number of characters in line i of lookupTable
    if character it of line i of lookupTable is “,” then
      put empty into character it of line i of lookupTable
    end if
    
    put line i of lookupTable into line i of card field “subscribers”
  end repeat
  set the cursor to arrow
End DoALookUp

----------------------------------------------
-- Generic utilities
--
-- SelectLine : return the content of the line
--              clicked in by the user (card field only)
--
-- isBlank:     return true if the field is empty
--              or contains just white space.
----------------------------------------------

on log mess
  -- the idea for a network log is borrowed
  -- from Chris Allen.
  
  repeat while the number of chars of cd fld “Log” > 15000
    delete line 1 of cd fld “Log”
  end repeat
  
  put “•”&&mess&return after cd fld “log”
end log

Function SelectLine theField
  --
  -- select a line from the given card field
  -- Accepts the short name of a card field as input
  --
  put empty into my_answer
  
  --
  -- When selecting a line from a field,
  -- you need to take into account that the
  -- field may have been scrolled.
  --
  -- To determine the number of scrolled lines
  -- divide the number of scrolled pixels by the
  -- number of pixels per line
  --
  
  put the scroll of card field theField into box_top
  put the textheight of card field theField into tsize
  put round( box_top/tsize ) into lineNum
  
  --
  -- You get a mouseup in global coordinates
  -- To find the line hit, you need to convert
  -- to local coordinates.
  --
  
  put item 2 of the rect of card field theField into x_global_offset
  put item 2 of the clickloc into x_hit
  
  -- Once you find the mousehit point,
  -- convert it to a line relative to top of box.
  -- This “relative line” is added to the number
  -- of scrolled lines to determine the actual
  -- line number (e.g. if 10 lines have been scrolled
  -- then the first line in the field is 11, not 1).
  --
  subtract x_global_offset from x_hit
  add trunc( x_hit/tsize) to lineNum
  
  --
  -- in the arithmetic, line numbers will be
  -- normalized to 0 rather than 1.  Hypercard
  -- starts at line 1 so adjust the offset.
  --
  add 1 to lineNum
  put line lineNum of card field theField into my_answer
  
  return my_answer
end SelectLine

function is_blank string
  get character 1 of string
  
  if it is space or it is empty or it is tab or it is return then
    return true
  else
    return false
  end if
end is_blank

----------------------------------------------
-- Queue Management
--
-- These routines handle management of the message
-- queue.  Excuse the logic; if Hypercard has an
-- Achille’s heel, it’s the lack of useful data
-- structures.
--
-- Addmessage : add a message to end of queue
-- RemoveMessage: remove a message from the queue
----------------------------------------------

on AddMessage the_memo
  global message_queue
  
  get the number of lines in  message_queue
  put the_memo into line it+1 of message_queue
end addMessage

on NextMessage
  --
  -- removing a message implies that the removed
  -- message get put into the message_pending container
  -- This method should only be called once the pending
  -- message has been serviced
  --
  global message_queue, message_pending
  
  if message_pending is not empty then log message_pending
  
  put line 1 of message_queue into message_pending
  
  delete line 1 of message_queue
  
end NextMessage

-----------------------------------------------
-- Message Management
--
-- These routines handle management of the possible
-- messages that can be received by the network.
-- all messages have the form:
--
-- Line 1:    Message Type (token)
-- Line 2:    Message Sender (string)
-- Line 3..n: Message dependent data
--
-----------------------------------------------

Function BuildHeader mess, name
  put mess into line 1 of temp
  put name into line 2 of temp
  return temp
end BuildHeader

on call someone
  adspCall someone
  NextMessage
  -- notice that this message needs to be pended also
  -- The block will be cleared by the connectionMade method
end call

on hangup someone
  ADSPHangup someone
  NextMessage
end hangup

on PENDING
  -- This is a “wait for completion” message.  Because
  -- it does nothing, it blocks the message_queue until
  -- some data is received.  The receive method will clear
  -- the pending message.  Only the nextMessage method can
  -- unblock the queue.  Notice that nextMessage should get
  -- called only after the expected data is returned.
end PENDING

on getcatalog server, folder
  global myEntityName
  --
  -- Client is asking for a directory of the requested
  -- folder. Service the request...
  --
  if server is not empty then
    put BuildHeader( “get catalog”, myentityname) into send_this_message
    
    put folder into line 3 of send_this_message
    
    ADSPTalk server, send_this_message
    
  end if
  NextMessage
end getcatalog

on getVolumeList server
  global myEntityName
  
  if server is not empty then
    put BuildHeader(“get volumes”, myEntityName ) into send_this_message
    
    Log server
    log send_this_message
    
    adsptalk server, send_this_message
    
  end if
  NextMessage
end getvolumeList

----------------------------------------------
--
-- Message request methods.  Requests are assembled
-- by these methods and added to the request queue
--
----------------------------------------------

on request_volumes
  global message_queue
  
  put selectline( the short name of the target ) into theServer
  if theServer is not empty then
    put theServer into card field “current server”
    
    AddMessage “Call”&&quote&theserver&quote
    AddMessage “Pending”
    AddMessage “getVolumelist”&&quote&theserver&quote
    AddMessage “Pending”
    AddMessage “Hangup”&&quote&theserver&quote
  end if
  
end request_volumes

on request_catalog
  global message_queue
  
  put card field “current server” into theServer
  if theServer is not empty then
    
    AddMessage “Call”&&quote&theserver&quote
    AddMessage “Pending”
    put quote&cd fld “current pathname”&quote into temp
    AddMessage “getcatalog”&&quote&theserver&quote&”,”&temp
    AddMessage “Pending”
    AddMessage “Hangup”&&quote&theserver&quote
  end if
  
end request_catalog

-----------------------------------------------
-- Message response methods.  These methods will
-- respond to a particular message from a remote
-- end in whatever manner is appropriate.  Note
-- that responses don’t get queued, they go
-- right out on the line.
--
-- Response messages take the same form as request
-- messages.  Notice that the response methods
-- use myentityname to tell the client which server
-- is providing the response.
-----------------------------------------------

on Receive something
  --
  -- A request that was made in the past is
  -- being addressed, do something with the
  -- incoming data (for now, just display it)”
  --
  if “volume” is in line 1 of something then
    log something
  end if
  
  if “catalog” is in line 1 of something then
    delete line 1 of something
    put line 1 of something into cd fld “current server”
    delete line 1 of something
    put something into cd fld “current catalog”
  end if
  
  NextMessage
end receive something
on Handle request
  --
  -- incoming caller is making a request, do
  -- something about it
  --
  
  get word 2 of line 1 of request
  put line 2 of request into to_client
  
  if “catalog” is in it then
    put line 3 of request into of_folder
    return_catalog of_folder, to_client
  end if
  
  if “volumes” is in it then
    return_volume_list to_client
  end if
  
end handle

on return_catalog folder, client
  global myEntityName
  
  if client is not empty then
    put BuildHeader( “put catalog”, myEntityName ) into the_response
    
    Put GetCatalog( “”, directoryID ) into temp
    put the_response&return&temp into the_response
    
    ADSPTalk client, the_response
    
  end if
end return_catalog

on return_volume_list client
  global myentityname
  
  if client is not empty then
    put BuildHeader( “put volumes”, myentityname )¬
    into the_response
    
    Put Volumes() into temp
    put the_response&return&temp into the_response
    
    ADSPTalk client, the_response
    
  end if
end return_volume_list

Listing 1. Stack Methods for HyperServer

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

Duplicate Annihilator 5.7.5 - Find and d...
Duplicate Annihilator takes on the time-consuming task of comparing the images in your iPhoto library using effective algorithms to make sure that no duplicate escapes. Duplicate Annihilator... Read more
BusyContacts 1.0.2 - Fast, efficient con...
BusyContacts is a contact manager for OS X that makes creating, finding, and managing contacts faster and more efficient. It brings to contact management the same power, flexibility, and sharing... Read more
Capture One Pro 8.2.0.82 - RAW workflow...
Capture One Pro 8 is a professional RAW converter offering you ultimate image quality with accurate colors and incredible detail from more than 300 high-end cameras -- straight out of the box. It... Read more
Backblaze 4.0.0.872 - Online backup serv...
Backblaze is an online backup service designed from the ground-up for the Mac.With unlimited storage available for $5 per month, as well as a free 15-day trial, peace of mind is within reach with... Read more
Little Snitch 3.5.2 - Alerts you about o...
Little Snitch gives you control over your private outgoing data. Track background activity As soon as your computer connects to the Internet, applications often have permission to send any... Read more
Monolingual 1.6.4 - Remove unwanted OS X...
Monolingual is a program for removing unnecesary language resources from OS X, in order to reclaim several hundred megabytes of disk space. If you use your computer in only one (human) language, you... Read more
CleanApp 5.0 - Application deinstaller a...
CleanApp is an application deinstaller and archiver.... Your hard drive gets fuller day by day, but do you know why? CleanApp 5 provides you with insights how to reclaim disk space. There are... Read more
Fantastical 2.0 - Create calendar events...
Fantastical is the Mac calendar you'll actually enjoy using. Creating an event with Fantastical is quick, easy, and fun: Open Fantastical with a single click or keystroke Type in your event details... Read more
Cocktail 8.2 - General maintenance and o...
Cocktail is a general purpose utility for OS X that lets you clean, repair and optimize your Mac. It is a powerful digital toolset that helps hundreds of thousands of Mac users around the world get... Read more
Direct Mail 4.0.4 - Create and send grea...
Direct Mail is an easy-to-use, fully-featured email marketing app purpose-built for OS X. It lets you create and send great looking email campaigns. Start your newsletter by selecting from a gallery... Read more

These are All the Apple Watch Apps and G...
The Apple Watch is less than a month from hitting store shelves, and once you get your hands on it you're probably going to want some apps and games to install. Fear not! We've compiled a list of all the Apple Watch apps and games we've been able to... | Read more »
Appy to Have Known You - Lee Hamlet Look...
Being at 148Apps these past 2 years has been an awesome experience that has taught me a great deal, and working with such a great team has been a privilege. Thank you to Rob Rich, and to both Rob LeFebvre and Jeff Scott before him, for helping me... | Read more »
Hands-On With Allstar Heroes - A Promisi...
Let’s get this out of the way quickly. Allstar Heroes looks a lot like a certain other recent action RPG release, but it turns out that while it’s not yet available here, Allstar Heroes has been around for much longer than that other title. Now that... | Read more »
Macho Man and Steve Austin Join the Rank...
WWE Immortals, by Warner Bros. Interactive Entertainment and WWE, has gotten a superstar update. You'll now have access to Macho Man Randy Savage and Steve Austin. Both characters have two different versions: Macho Man Randy Savage Renegade or Macho... | Read more »
Fearless Fantasy is Fantastic for the iF...
I actually had my first look at Fearless Fantasy last year at E3, but it was on a PC so there wasn't much for me to talk about. But now that I've been able to play with a pre-release version of the iOS build, there's quite a bit for me to talk... | Read more »
MLB Manager 2015 (Games)
MLB Manager 2015 5.0.14 Device: iOS Universal Category: Games Price: $4.99, Version: 5.0.14 (iTunes) Description: Guide your favorite MLB franchise to glory! MLB Manager 2015, officially licensed by MLB.com and based on the award-... | Read more »
Breath of Light (Games)
Breath of Light 1.0.1421 Device: iOS Universal Category: Games Price: $2.99, Version: 1.0.1421 (iTunes) Description: Hold a quiet moment. Breath of Light is a meditative and beautiful puzzle game with a hypnotic soundtrack by... | Read more »
WWE WrestleMania Tags into the App Store
Are You ready to rumble? The official WWE WrestleMania app, by World Wrestling Entertainment, is now available. Now you can get all your WrestleMania info in one place before anyone else. The app offers details on superstar signings, interactive... | Read more »
Bio Inc's New Expansion is Infectin...
Bio Inc., by DryGin Studios, is the real time strategy game where you infect a human body with the worst virus your evil brain can design. Recently, the game was updated to add a whole lot of new features. Now you can play the new “Lethal”... | Read more »
The Monocular Minion is Here! Despicable...
Despicable Me: Minion Rush, by Gameloft, is introducing a new runner to the mix in their latest update. Now you can play as Carl, the prankster minion. Carl has a few new abilities to play with, including running at a higher speed from the start.... | Read more »

Price Scanner via MacPrices.net

13-inch 2.5GHz MacBook Pro (refurbished) avai...
The Apple Store has Apple Certified Refurbished 13″ 2.5GHz MacBook Pros available for $829, or $270 off the cost of new models. Apple’s one-year warranty is standard, and shipping is free: - 13″ 2.... Read more
Save up to $80 on iPad Air 2s, NY tax only, f...
 B&H Photo has iPad Air 2s on sale for $80 off MSRP including free shipping plus NY sales tax only: - 16GB iPad Air 2 WiFi: $469.99 $30 off - 64GB iPad Air 2 WiFi: $549.99 $50 off - 128GB iPad... Read more
iMacs on sale for up to $205 off MSRP
B&H Photo has 21″ and 27″ iMacs on sale for up to $205 off MSRP including free shipping plus NY sales tax only: - 21″ 1.4GHz iMac: $1019 $80 off - 21″ 2.7GHz iMac: $1189 $110 off - 21″ 2.9GHz... Read more
Färbe Technik Offers iPhone Battery Charge LI...
Färbe Technik, which manufactures and markets of mobile accessories for Apple, Blackberry and Samsung mobile devices, is offering tips on how to keep your iPhone charged while in the field: •... Read more
Electronic Recyclers International CEO Urges...
Citing a recent story on CNBC about concerns some security professionals have about the forthcoming Apple Watch, John Shegerian, Chairman and CEO of Electronic Recyclers International (ERI), the... Read more
Save up to $380 with Apple refurbished iMacs
The Apple Store has Apple Certified Refurbished iMacs available for up to $380 off the cost of new models. Apple’s one-year warranty is standard, and shipping is free: - 27″ 3.5GHz 5K iMac – $2119 $... Read more
Mac minis on sale for up to $75 off, starting...
MacMall has Mac minis on sale for up to $75 off MSRP including free shipping. Their prices are the lowest available for these models from any reseller: - 1.4GHz Mac mini: $459.99 $40 off - 2.6GHz Mac... Read more
College Student Deals: Additional $50 off Mac...
Take an additional $50 off all MacBooks and iMacs at Best Buy Online with their College Students Deals Savings, valid through April 11, 2015. Anyone with a valid .EDU email address can take advantage... Read more
Mac Pros on sale for up to $260 off MSRP
B&H Photo has Mac Pros on sale for up to $260 off MSRP. Shipping is free, and B&H charges sales tax in NY only: - 3.7GHz 4-core Mac Pro: $2799, $200 off MSRP - 3.5GHz 6-core Mac Pro: $3719.99... Read more
13-inch 2.5GHz MacBook Pro on sale for $100 o...
B&H Photo has the 13″ 2.5GHz MacBook Pro on sale for $999 including free shipping plus NY sales tax only. Their price is $100 off MSRP. Read more

Jobs Board

DevOps Software Engineer - *Apple* Pay, iOS...
**Job Summary** Imagine what you could do here. At Apple , great ideas have a way of becoming great products, services, and customer experiences very quickly. Bring Read more
*Apple* Retail - Multiple Positions (US) - A...
Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, you're also the Read more
Sr. Technical Services Consultant, *Apple*...
**Job Summary** Apple Professional Services (APS) has an opening for a senior technical position that contributes to Apple 's efforts for strategic and transactional Read more
Lead *Apple* Solutions Consultant - Retail...
**Job Summary** Job Summary The Lead ASC is an Apple employee who serves as the Apple business manager and influencer in a hyper-business critical Reseller's store Read more
*Apple* Pay - Site Reliability Engineer - Ap...
**Job Summary** Imagine what you could do here. At Apple , great ideas have a way of becoming great products, services, and customer experiences very quickly. Bring Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.