SunRPC beginner tips
RPC (Remote Procedure Calls) are used for making client/server programs where the client can call a function on the server without having to implement their own network code, they link in with rpcbind which is run on just about every system now days. It works by using a simple msg.x template, running it through a code generator rpcgen and linking the results with the client and server code.
I had to do 2 assignments this year for my distributed computing class using Sun’s RPC on Solaris.
RPC is extremely painful and there isn’t to much in the way of beginners resources. The server kept core dumping on me and the bit causing the problem was often in the RPC libs rather than my code. Normally this is caused by breaking memory allocation but its very hard to track down, gdb doesn’t really help.
A few tips i picked up while working on Sun RPC:
You can stop the server for backgrounding, allowing you to use standard printf’s for debugging. Just add -DRPC_SVC_FG to your servers compile line.
Correct memory management is crucial, any leaks no matter how minor will cause crashes with RPC.
Don’t leave any pointers undefined even if you haven’t put anything into them and are using a size variable of 0 (such as emptry arrays/strings), NULL them, SunRPC will try to free() any pointers after receiving the struct back which can cause your client to crash when it recives a successful response because its trying to free the memory before putting the actual response struct data in there, since they are undefined it will try to free random memory and segfault.
Make sure this applies to the both the sent and result struct, the server should automatically initialize the result struct as you can’t guarantee the client has passed a valid empty struct
Make sure you test more than one remote function in a row, quite a few memory errors will not manifest until the server attempts to process the next request AFTER the bad function has worked. If your server is seg faulting on a function, make sure its actually not the previous function that is the problem.
Its much easier to use one universal message struct for all the remote functions to be passed back and forward rather than making a new struct type for each function. Possibly slightly less efficient but not by too much for simple projects.
Its much easier to let the server do all the work, if the information is just getting printed to the console passback a string rather than a struct with the information in it. Probably not a good practice for real life usage though, but much eaiser for learning basic RPC.
The Linux rpcgen seems to be fairly horrible, most of my code wouldn’t work with it, doesn’t seem to support generating stubs, maybe there is an entirely different approach for programming rpc in Linux but I couldn’t find it. Current version might be broken. Things like enums just wouldn’t work for me (which awas a problem because my 1st assignment specified the them). Some sample code I downloaded worked fine, others just wouldn’t.
You can make your code thread safe and handling concurrent connections with ‘rpcgen -MA’, you will still need semaphores or some other form of concurrency control.
Sun’s rpcgen has the ability to generate template stubs for server and client code with -a, very useful, they are called msg_server.c and msg_client.c, done actually modify them as they will be overridden next time, just copy em. Can be used in combination with the -aAM for threadsafe.
Code generated by rpcgen is outdated and will give warning when compiled but still works on, you can fix the stubs by adding int befoure main and such but the templates you will probably need to live with.
Variable sized arrays in the template file are declared with not , you can specify a max length ie ,  will do fixed size arrays like normal.
RPC has a ‘string’ variable type in the template file, this is the equivalent of c’s char* (notice its string, not c++’s String) for example: ‘string name;’, your c code will see this as a normal char*
A array in the RPC template file will make a struct with name.name_val and name.name_len
char* for strings in the template file was causing me pain, I don’t remember why but there is probally a reason for string.
Remember to NULL terminate your strings when they are passed around, otherwise RPC won’t know when to stop freeing
Functions can only accept one struct, so make sure it contains everything needed.
Sometimes poking into the files generated by the template can help understanding some problems, such as typos in msg.x not being caught by rpcgen but causing your source to fail compiling.
If possible use something other than RPC (CORBA, XMLRPC, SOAP), I haven’t used them but they can’t be worse. They might have some overhead though.
http://www.cdk3.net/rmi/Ed2/SunRPC.pdf – SunRPC definition.
http://www.cs.cf.ac.uk/Dave/C/node34.html – Some basic rpc examples, the way it works is a bit different to the stubs generated by Sun’s rpcgen but its fairly easy to work out the changes needed.
http://www2.cs.uregina.ca/~hamilton/courses/430/notes/rpc.html – Same again, includes a linked list example.