tar
your files to a file called hw4.tar
and email it as an attachment to mao@cs.fsu.edu, along with a cc to asriniva@cs.fsu.edu. Make sure that you do not include the executable, any object files, or core dump file!
tar xvf hw4.tar
server
using the following command:
make server
server Port
(where Port is the port number of the server.
f
, will take an integer as its argument and return a
double precision number. The client will inform the server about the
argument, say N
. If the server does not know the function
definition, then the client will provide the function definition in
C. The server is responsible for compiling and running a program that
will provide it the value of f(N)
. This value is then
sent to the client.
Further details are given below.
After establishing connection with a server, a client will request
a service by sending the server a string: #@#COMPUTE function
version argument #@#ENDCOMPUTE
. function
is a string
of at most 50 characters (only upper or lower case letters), which
gives the name of a function to compute, version
is a
version number for the function's definition, which is a string of at
most 50 characters (upper or lower case letters, digits, or periods),
and argument
is a string of digits (at most 9). We will
explain "version
" further, later.
If this message from the client does not follow the correct
format, then the server should send the client a string:
#@#ERROR Invalid request #@#ENDERROR
and close the
socket. Otherwise, it checks to see if it has the definition of this
function with the same version number. If it has this function's
definition, then it evaluates the function with the desired
argument, and sends the result to the client in a string of the form:
#@#RESULT answer #@#ENDRESULT
, where answer
is a string
of digits, possibly including a period, representing the value of the
function. The server then closes this socket, and the client closes
the socket on receipt of the result.
If the server does not have the function's definition, then it
sends the following response to the client: #@#DEFINEFUNCTION
function version #@#ENDDEFINEFUNCTION
, to which the client
responds by sending #@#FUNCTIONDEFINITION C-code
#@#ENDFUNCTIONDEFINITION
, where C-code
is C code for
the function definition. If this message from the client does not follow the correct
format, then the server should send the client a string:
#@#ERROR Invalid definition #@#ENDERROR
and close the
socket.
Note that C-code
will not be a
complete C program. However, it is guaranteed to have a non-static
function called function
that takes an int
argument and which returns a double
. It may contain other
(static) functions too, and perhaps static "global" (file scope)
variables. The server should be able to save the definition to a C
file and compile it with gcc -c
and create an object
file. (It may and then link it with an appropriate file to create an
executable and run it.) The server will ensure that the function is
evaluated, and send the result to the client as described
earlier. Then the client and server close their sockets, as described
earlier.
The version number is useful for the following
purpose. Two different clients may define the same function name, say
pi
. However, the function definitions may be
different. We want some mechanism to let clients specify version
numbers that are likely to be unique. For example, if I write a
client, I may give a version number: ashok.cs.fsu.edu.N
,
where N
will be 1
initially. I may use the
same version number in several different service requests to the
server, until I change the function definition (for example, if I
discovered some error in the previous definition). The first time the
server encounters a new ordered pair
(function-name,version-number)
, it will request the
client for its definition, and keep a record of having obtained this
definition. On subsequent requests for this same pair, it will use the
definition it already has.
You should implement a concurrent server using pthreads.
#@#COMPUTE function version argument #@#ENDCOMPUTE
is expected, the server should check for the following errors: (i) the correct tags to start and end the message, (ii) the correct number of fields, and (iii) if argument
is a string representing an integer.
#@#FUNCTIONDEFINITION C-code
#@#ENDFUNCTIONDEFINITION
is expected, the server should check for the following errors: (i) the correct tags to start and end the message, and (ii) if there is a non-empty string (representing C-code
) between the tags (if a non-empty string is present, then you can assume that it contains a correct function definition).
-c
option to gcc
. It can compile the whole program, including main
.
#@#FUNCTIONDEFINITION ... #@#ENDFUNCTIONDEFINITION
when it expected #@#COMPUTE ... #@#ENDCOMPUTE
or it is sent #@#COMPUTE ... #@#ENDCOMPUTE
when it expected #@#FUNCTIONDEFINITION ... #@#ENDFUNCTIONDEFINITION
.
client server-address port
client 128.186.120.33 50002
1 0
1 1
2 0
0