CSCI-4220 Network Programming

Project 1 - Layered System
Frequently Asked Questions


Q: In class you showed us the output generated when you ran the test code with your layers.c, can you provide us with this output?

A:I've made an executable available on the CS machines (works only on a BSD machine like monica.cs.rpi.edu) that you can play with. You can set a debugging level on the command line and control how verbose the program is. The program is at ~hollingd/public.html/netprog/P1code/testprog (on the CS machines). Usage is like this:

testprog [-d #] astring
The program is based on the test code provided for P1 (uses pipes and fork), the child process sends "astring" to the parent. The lower a number you specify after "-d", the more debugging output you will see.

-d 3 means only layer 3 prints debugging information.
-d 2 means layer 3 and 2 print debugging information.
-d 1 means layers 3,2 and 1 print debugging information.
-d 0 means layers 0,1,2 and 3 print debugging information
Here is a sample run:
>  ./testprog -d 1 "Hello Dave"
Starting - debug level is 1, sending string <Hello Dave>
CID 0 is for pipes 5 and 4
CID 0 is for pipes 3 and 6
[PARENT]:l3_read called - reading at most 100 chars
[CHILD]: l3_write sending Hello Dave
[PARENT]:  l2_read called
[CHILD]:   l2_write called sending a H
[PARENT]:   l1_read called
[CHILD]:    l1_write sending: H
[PARENT]:   l1_read returning a: H
 [CHILD]:    l1_read called
[PARENT]:   l1_write sending: H
[CHILD]:    l1_read returning a: H
 [PARENT]:l3_read got a H (72) from l2_read
[CHILD]:   l2_write called sending a e
[PARENT]:  l2_read called
[CHILD]:    l1_write sending: e
[PARENT]:   l1_read called
 [CHILD]:    l1_read called
[PARENT]:   l1_read returning a: e
[PARENT]:   l1_write sending: e
[CHILD]:    l1_read returning a: e
 [PARENT]:l3_read got a e (101) from l2_read
[CHILD]:   l2_write called sending a l
[PARENT]:  l2_read called
[CHILD]:    l1_write sending: l
[PARENT]:   l1_read called
 [CHILD]:    l1_read called
[PARENT]:   l1_read returning a: l
[PARENT]:   l1_write sending: l
[CHILD]:    l1_read returning a: l
 [PARENT]:l3_read got a l (108) from l2_read
[CHILD]:   l2_write called sending a l
[PARENT]:  l2_read called
[CHILD]:    l1_write sending: l
[PARENT]:   l1_read called
 [CHILD]:    l1_read called
[PARENT]:   l1_read returning a: l
[PARENT]:   l1_write sending: l
[CHILD]:    l1_read returning a: l
 [PARENT]:l3_read got a l (108) from l2_read
[CHILD]:   l2_write called sending a o
[PARENT]:  l2_read called
[CHILD]:    l1_write sending: o
[PARENT]:   l1_read called
 [CHILD]:    l1_read called
[PARENT]:   l1_read returning a: o
[PARENT]:   l1_write sending: o
[CHILD]:    l1_read returning a: o
 [PARENT]:l3_read got a o (111) from l2_read
[CHILD]:   l2_write called sending a
[PARENT]:  l2_read called
[CHILD]:    l1_write sending:
[PARENT]:   l1_read called
 [CHILD]:    l1_read called
[PARENT]:   l1_read returning a:
[PARENT]:   l1_write sending:
[CHILD]:    l1_read returning a:
 [PARENT]:l3_read got a   (32) from l2_read
[CHILD]:   l2_write called sending a D
[PARENT]:  l2_read called
[CHILD]:    l1_write sending: D
[PARENT]:   l1_read called
[PARENT]:   l1_read returning a: D
 [CHILD]:    l1_read called
[PARENT]:   l1_write sending: D
[CHILD]:    l1_read returning a: D
 [PARENT]:l3_read got a D (68) from l2_read
[CHILD]:   l2_write called sending a a
[PARENT]:  l2_read called
[CHILD]:    l1_write sending: a
[PARENT]:   l1_read called
 [CHILD]:    l1_read called
[PARENT]:   l1_read returning a: a
[PARENT]:   l1_write sending: a
[CHILD]:    l1_read returning a: a
 [PARENT]:l3_read got a a (97) from l2_read
[CHILD]:   l2_write called sending a v
[PARENT]:  l2_read called
[CHILD]:    l1_write sending: v
[PARENT]:   l1_read called
 [CHILD]:    l1_read called
[PARENT]:   l1_read returning a: v
[PARENT]:   l1_write sending: v
[CHILD]:    l1_read returning a: v
 [PARENT]:l3_read got a v (118) from l2_read
[CHILD]:   l2_write called sending a e
[PARENT]:  l2_read called
[CHILD]:    l1_write sending: e
[PARENT]:   l1_read called
 [CHILD]:    l1_read called
[PARENT]:   l1_read returning a: e
[PARENT]:   l1_write sending: e
[CHILD]:    l1_read returning a: e
 [PARENT]:l3_read got a e (101) from l2_read
[CHILD]:   l2_write called sending a
[PARENT]:  l2_read called
[CHILD]:    l1_write sending:
 [CHILD]:    l1_read called
[PARENT]:   l1_read called
[PARENT]:   l1_read returning a:
[PARENT]:   l1_write sending:
[CHILD]:    l1_read returning a:
 [PARENT]:l3_read got a  (0) from l2_read
[PARENT]:l3_read returning, got the string <Hello Dave>
MESSAGE RECEIVED WAS <Hello Dave>
Problems or questions to hollingd@cs.rpi.edu

Q: How can layer2 send acknowledgments, from l2_read() I would somehow need to "know" how to send something to the other end?

A: My description of the "communication endpoints" represented by the CIDs is incomplete and should include the following statement: CIDs represent a full duplex communication link.

So, l2_read() can use the CID given to call l1_write() or l1_read().

Q: What if data is lost? What is bits are reversed? What if the data is received, but the ACK get's lost. What if a dog eats 3 of every 8 bits? What if ... ?

A: In general you can't deal with every contingency unless your code is part of the operating system (and can operate asynchronously). Don't complicate the assignment, just make sure that your code works as long as everything else works! This is supposed to be a simple project that does not involve any system programming (no timers, signals, interrupts, multiplexed I/O, etc.) that simply makes sure you have some understanding of layered systems.

Q: When I implement l2_write(),I add sequencer to the data and write it. Before sending next data, I call l1_read() to read charactor ack. If the ack is not I need, then I 'll resend the data. I think I can't read many times before resending because I have only sent one byte, so receiver can only send one ack, so I can only read one byte before sending another data, If I read many times before sending another byte, the process will block when I read second time because there is nothing to be read. Am I right? and if the ack is lost or the byte I have send is lost, then there will be nothing to read, so when I call L1_read to read ack, the process will block. How to deal this case? could you give me any hint?

A: Your layer2 protocol is more than requested - you can simplify things by not resending, just return an error if you get an ACK that is not what you expect. If you really do resend - I don't know how (using the scheme you describe), the reader would know what is resent data and what is not. The purpose of the project is not to create a bullet-proof reliable service at layer 2, but just to make sure you understand what a layered system is.

Q: in l1_read(int cid, char * buff) Is buff just a char or is it a string of bits when this function returns?

A: It is a single char (byte), not a string of bits. You have to build this value from the 8 bits you (I'm assuming here) read using l0_read(). In C you can do this with bitwise operators |, &, <<, and >> . For example, to set the nth bit (rightmost bit is bit 0) in a char named x to be the value 1 you can do this:

x |= 0x01 << n;
This takes the pattern 00000001, shifts it left n times, and ORs the result with x (and saves the result of the OR in x). Similarly you can extract the value of the nth bit with something like this:
bitval = x & (0x01 << n);
Caution: you need to be a little careful about how you do things, the shift operators depend on whether a value is signed or not. See any C reference for details.

Q: What's up with the CS accounts?

A: We requested accounts for all students who were on the official roster as of Friday, Jan 14th. You should receive email from labstaff@cs.rpi.edu providing you with the details of your account on the Computer Science Unix machines. As far as I know this has not yet happened.

Q: How do I submit my project?

A: The automated submission script has not yet been installed, we will provide details when it's ready for action. If it is not ready by Thursday, Jan 20th we will go with a manual submission system (email to a human).

Q: Is there test code available?

A: Yup - it's here