FindServer

From BeebWiki
Jump to: navigation, search

Most of the traffic between computers on a network is the in the form of a client machine communicating with a server machine. The client machine is the computer at which a person logs on and the server machine is a machine such as a File Server or Printer Server. However other types of servers can be added to a network.

The difficulty is for a client machine to determine which computer on the network is the server, and what network port to use. For a File Server and a Printer Server this is not a problem as the NFS and NetPrint systems have built-in defaults.

With other types of servers clients should use the FindServer protocol to locate a particular type of server and the port numbers further communication should use.

Find Server Protocol

Client to server

 port             &B0
 control byte     &80
 Data             name of server in capitals padded with spaces to a length
                  of eight characters as ASCII data.

Server to client

 port             &B1
 control byte     &80
 Data             0 or error number
 Data+1           base port for further exchanges
 Data+2           binary version number of server software, eg &12 for 1.20
 Data+3           server type (8 characters, format as for Client to server)
 Data+11          length of server name (0 if not present)
 Data+12          server name (optional)
 Data+12+NameLen  server dependant information or 0-terminated error string
                  if ?Data<>0

All servers should respond to the wildcard name of eight spaces. This makes it possible to interrogate your network to find all the servers available. The server will respond with a maximum of 32 bytes to a FindServer request.

Coding

Client Program

 REM > FindServer
 REM Use FindServer protocol to find a server
 :
 DIM ctrl% 31:X%=ctrl%:Y%=X%DIV256
 DIM rxBuf% 31,txBuf% 15:rx%=0:tx%=0
 :
 ON ERROR REPORT:PROCNet_RxKill(tx%):PRINT:END
 :
 rx%=FNNet_RxOpen(0,&B1,rxBuf%,&20)
 $txBuf%="DESPOOL "              :REM Look for a DESPOOL server
 $txBuf%="MUGINS  "              :REM Look for a MUGINS server
 $txBuf%="RISCOS  "              :REM Look for a RISCOS server
 $txBuf%="TELETEXT"              :REM Look for a TELETEXT server
 $txBuf%="UNIX    "              :REM Look for a UNIX server
 $txBuf%="        "              :REM Look for all server types
 try%=10
 REPEAT
   tx%=FNNet_TxCount(&FFFF,&80,&B0,txBuf%,8,0,0,0)
   IF tx% THEN PRINT FNNet_Err(tx%):END
   rxok%=FNNet_Rx(rx%)
   IF NOT rxok%:A%=TIME+50:REPEATUNTILTIME>A%:try%=try%-1
 UNTIL rxok% OR try%<1
 IF NOT rxok% THEN PROCNet_RxKill(rx%):PRINT "No server found":END
 rxnum%=FNNet_RxRead(rx%):stn%=X%!3
 PRINT "Server found on station ";FNNet_Stn(stn%)
 IF ?rxBuf% THEN PRINT "Server error: ";$(rxBuf%+1):END
 rxBuf%?(12+rxBuf%?11)=13:name$=$(rxBuf%+12)
 rxBuf%?11=13:server$=$(rxBuf%+3)
 vers%=rxBuf%?2
 portBase%=rxBuf%?1
 PRINT "Type: ";server$;"   Name: ";name$
 PRINT "Base port: &";FNh0(portBase%,2);"   Version: ";vers%DIV16;".";(vers%AND15)*10
 END

This code uses the Net library.

Server Program

 REM > ServReply
 REM Sample to to respond to FindServer requests
 :
 DIM ctrl% 15,txBuf% 255,rxBuf% 127,svBuf% 15:X%=ctrl%:Y%=X%DIV256
 MyName$="MUGINS  "              :REM My server type
 MyPort%=ASC"M"                  :REM Port for clients to use to talk to me
 ver$="1.00"                     :REM My version number
 svNum%=0:rxNum%=0
 PROCopenServ:PROCopenAction     :REM Listen to server port and command port
 REPEAT
   IFFNNet_Rx(svNum%):PROCserver:PROCopenServ   :REM FindServer request
   IFFNNet_Rx(rxNum%):PROCaction:PROCopenAction :REM Action request
 UNTIL FALSE
 :
 DEFPROCopenServ:svNum%=FNNet_RxOpen(0,&B0,svBuf%,12):ENDPROC
 DEFPROCopenAction:rxNum%=FNNet_RxOpen(0,MyPort%,rxBuf%,256):ENDPROC
 :
 DEFPROCserver:rx%=FNNet_RxRead(svNum%):stn%=X%!3:svBuf%?8=13
 IF$svBuf%<>MyName$ AND $svBuf%<>"        ":ENDPROC
 ?txBuf%=0:txBuf%?1=MyPort%:txBuf%?2=EVAL("&"+STR$(10*VALver$))
 $(txBuf%+3)=MyName$:txBuf%?11=0
 REM Additional data can be returned, txBuf%?11=length, txBuf%+12=data
 tx%=FNNet_Tx(stn%,&80,&B1,txBuf%,12+txBuf%?11,0)
 ENDPROC
 :
 DEFPROCaction
 rx%=FNNet_RxRead(rxNum%)
 :
 REM Do something with contents of received data
 :
 ENDPROC

This code uses the Net library.

References

  • SJ MDFS Manual, Chapter 10
  • RISC OS PRM

Jgharston 23:29, 15 May 2009 (UTC)