The purpose for having programming assignments in this class is to give you experience in sockets programming, multithreading, and routing. Programming for networking can be done inside the OS kernel or at the application-level. Since the OS class (CSCI 350) is not a prerequisite for this class, we have to run our networks at the application-level. Although all we will be doing is developing code at the application-level, some of what you will be doing can be considered "systems programming" when your code provides services (such as routing) to other networking applications.
All programming assignments are individual assignments. Although you are encouraged to "work with" your classmates at a "high level". When it's time to write code, make sure you write your code privately. Technically speaking, "sharing" a single line of code or pseudo-code with your classmates is considered cheating. If you don't know how to work with another person and not end up "sharing/copying" code, you are advised not to work together with your classmates at all in programming assignments.
We will not give out "solutions" to any programming assignments even though it may seem that some programming assignments can use a previous programming assignment as a starting point. You should start every programming assignment from scratch and use your experience from previous assignments to write better code! You are also expected to do all the labs becuase the purpose of the labs is to get you started on programming assignments. If your program is not working, you are expected to come to office hours and helpdesk hours to seek help, although none of the teaching staff will be permitted to write code for you or debug code for you. The bottomline is that if you are not proficient at programming and debugging, you need to be prepared to spend a lot of time getting good at programming and debugger!
Access to programming assignments is restricted. These specs are private and you do not permissions to post/display these specs and your work based on these specs in a public place.
We will use the following percentages for figuring out your overall grade for your programming assignments:
All programming assignments must compile and run on a standard 32-bit Ubuntu 16.04 Linux system running inside a virtual machine on VirtualBox (please see installation instructions regarding how to setup such a system). One major advantage of using a virtual machine is that you can install as many copies as you want. For example, you can have one 32-bit Ubuntu 16.04 Linux system for development, one standard 32-bit Ubuntu 16.04 Linux system for final testing (and keep this virtual machine as "clean" as possible), one for doing experiments or whatever, etc.
I strongly discourage that you install 32-bit Ubuntu 16.04 directly over your hardware because you may run into hardware compatibility problems! I also strongly discourage that you do development work on Windows (such as using CMake or Microsoft Development Studio) or in a Mac OS X environment (such as using Xcode) because that can make your assignments ungradable and you will end up getting a very very low grade for your programming assignments (since graders are not allowed to grade on these platforms)! You should do all your development work on a standard 32-bit Ubuntu 16.04 system running on VirtualBox (i.e., with only permitted packages). This way, you can minimize the chance of unpleasant surprises.
Please note that a standard 32-bit Ubuntu 16.04 system would, once in a while, offer you to "upgrade" the system to the next release.
You must NOT do that (or run the "do-release-upgrade" command). If you do that, you will not be running Ubuntu 16.04 any more
and you may have to reinstall a brand-new Ubuntu 16.04 from scratch again (which is not all that difficult
once you get used to it).
If it ends up that there is no way to run a Ubuntu 16.04 system on it and the only machine you can use to work on our assignments is such an machine, then we have to have an alternative for you. Fortunately, there is such an alternative. It's not a perfect substitute for a Ubuntu 16.04 system, but it's usable. The name of the system is viterbi-scf1.usc.edu and it's a Linux server system running CentOS 7.6. It has no graphical user interface (and therefore, no IDE). It also does not have debugging tools such as valgrind and wireshark. But, as far as all our labs and programming assignments go, it's pretty much identical to a 32-bit standard Ubuntu 16.04 system (as long as you stick to the "standard" stuff on viterbi-scf1.usc.edu). If you have never used this system, please start a "terminal" program and type the following command to ssh into it:
ssh -X -Y YOURLOGIN@viterbi-scf1.usc.eduwhere YOURLOGIN is local-part of your USC E-mail address (and use your USC E-mail password when you are prompted for a password). If you were able to login, you can type the following to loging:
exitIf this doesn't work, please let me know as soon as possible.
Therefore, the bottom line is that graders can only grade in one of the two following systems:
The way normalization will be performed is as follows. I will normalize each PA grade according to the average and standard deviation for each grader for that PA and extrapolate your grade according to the overall class average and standard deviation. This normalization only applies to the grader-dependent part of your grade (i.e., without early/late submission extra credit and penalty. If the overall score you get for an assignment is X, your early/late submission extra credit and penalty is Y percent, your grader-dependent part of the score is Z = X / ((100+Y)/100). After normalization of the grader-dependent part of your score, if your score is Z', the score we will use to calculate your class grade would be X' = Z' × ((100+Y)/100). In the next two paragraphs, we will show you the basic idea of how to get Z' from Z by using an example.
Let's say that the average of a PA graded by a particular grader is 85 and standard deviation is 10 and you are graded by that grader and you got a score of 87.5 (i.e., average plus half a standard deviation), your normalized score will be the overall class average plus half of the overall class standard deviation for that PA. This means that if you were graded by an "easy grader", your normalized score may be lower than your original score. If you were graded by a "harsh grader", your normalized score may be higher than your original score. This is not a perfect system. But I think it's an improvement over not normalizing your scores at all. It should be clear that if all graders have the same averages and standard deviations, your normalized score would be identical to your original score.
Since the purpose of grade normalization is to normalize the difference in grading among the graders. For a programming assignment, the highest possible normalized grade anyone can get must still be the original maximum score assigned to that assignment, independent of the grader. Similarly, the lowest score one can get is 1 point if you have submitted something for grading.
Below are some very important information and requirement about our programming assignments. Please read them carefully so you understand all the rules we will stick to. If you are not sure about something, please send an e-mail to the instructor for clarification.
You must not look at, copy, or share any code fragments from your classmates or previous semesters to implement any programming assignment. Doing so would be considered cheating. You have committed plagiarism if you submit work done by others and claim that it's your own work.
It should be clear that you cannot use code written by other students in the current or a previous semester no matter what. As clearly in spelled out in the academic integrity policy of this class, if you have a copy of any of our programming assignments written by someone else, looking at the code or running the code is considered cheating, let alone copying code from it.
What about code you find online? First of all, it has to be publically available code (suh as stuff you find in stackoverflow.com). If it's a paid site or password protected, then it's not public. Also, you must not compile the code you got online into a library and have your code link to them. If you want to use any code online, you should extract what you need (make sure you understand them perfectly) and add it to your source code and cite where you got the source properly (see below). This way, you are making it clear that you did not write that piece of code and you are giving credit to others who have written the code.
What if you end up with the same code fragment as another student because you copy the code fragment from the same place online? This will make it look like you copied/shared code with another student. Well, this is why it's important to cite the source of each piece of code in your code properly. The proper way to cite your source is to do it inline in your C/C++ file. Please understand that it's improper to simply give citation in your README file. Here's what your code should look like when you use a piece of code you found on the Internet:
/* Begin code (derived) from [URL] */ /* If the code you got requires you to include its copyright information, put copyright here as well. */ [ code you copied or derived from above URL ] /* End code from [URL] */If you don't cite the code you got online properly and our plagiarism-catching software complains about identical code were found becuase you and somone else copied code from the same place online, you will lose 10 points for each such code fragment.
You have my permission to use code given to you as part of this class (i.e., from textbook or lecture slides). You do not need to cite such code.
You are allowed to submit modifications via e-mail to the instructor, up to 24 hours after the submission deadline (and preferably after the submission deadline). The first 3 lines of modifications are free of charge within this time frame. Additional modifications cost 3 points per line (each submission is worth 100 points).
One line (128 characters max) of change is defined as one of the following:
Afterwards, additional modifications cost 6 points per line until 7 days past the submission deadline. After 7 days past the submission deadline, an additional modification costs 15 points per line.
Please note that this applies to source code, Makefile, and README files. Please understand that the grader is NOT allowed to modify your source code or Makefile during grading.
Just want to be very clear about this... The free 3 lines of changes are only applicable if you submit them within 24 hours of the submission deadline. Also, a "modification" is NOT considered a "new submission". So, sending a "modification request" will not change the timestamp of the submission we grade.
I often get questions regarding segmentation faults and bus errors. Sometimes, these occue when one calls library functions such as malloc() or free(). Some students think this is some kind of a system bug. Well, it's often not. I will try to answer this type of questions here once and for all.
Chances are that you have corrupted memory (or have corrupted the memory allocation chain). Memory corruption means that a memory location got modified in a bad way and you have no idea when it happened or how it happened. It's as if it has gone bad all by itself. But since it really cannot go bad all by itself, it just be your code that somehow corrupted memory! When you notice that memory corruption has occurred, this usually implies that you have corrupted memory a while back. It just happened that when you call malloc() or free(), the corrupted memory caused a bus error or the execution of an illegal instruction. By the way, bus errors and illegal instructions are basically the same thing as segmentation faults. If you see something like "stack smash", it's another form of memory corruption bug (unless you really try to "smash the stack").
How does one corrupt memory (or corrupt the memory allocation chain)? You can write beyond an allocated memory block. You can free the same object twice. You can free an object that was not allocated. You can write to an object that's already freed. You can write to a portion of a stack space that is no longer valid. These bugs are hard to find because most of the them you only see that there is problem long time after you have "corrupted memory". We will talk about all this when we go over "dynamic storage allocation" in Ch 3 of the textbook.
If you have access to a professional/expensive debugging tool, it may be helpful. Otherwise, you just need to do binary search and see where the bug(s) might be. There's no magical cures in debugging memory corruption bugs, not even for professionals! I, unfortunately, do not have any magic tricks that can help anyone find memory corruption bugs.
One thing you might try is to include the following commandline argument when you run gcc to compile your code:
-fsanitize=addressThe above enables AddressSanitizer to catch certain memory corruption bugs. It's not a cure-all, so please do not exactly that it will find all your memory corruption bugs.
Another thing you might try is to temporarily turn off memory deallocation (if you suspect that you have freed the same object twice or freed an object that was not allocated). You can do the following to define free() as a no-op in a common header file when you are debugging:
#ifdef DEBUGGING_MEMORY_CORRUPTION #ifdef free #undef free #endif /* free */ #define free #endif /* DEBUGGING_MEMORY_CORRUPTION */Then use -DDEBUGGING_MEMORY_CORRUPTION as a commandline argument when you run g++ to use this trick.
As your code gets more and more complicated, you may get more of these bugs. This is one reason why you want to keep your code nice and clean.
On Linux, one very useful tool for finding memory corruption bugs is valgrind. If you have installed Ubuntu 16.04 on your laptop/desktop, you should give it a try. Just prefix your commandline by "valgrind" (or "valgrind --tool=exp-sgcheck") and read the output carefully. Figure out why valgrind is complaining and fix only the first bug it complains about. Although valgrind cannot catch every memory corruption bug, it does a pretty good job. For more details, please see the PA1 FAQ item about valgrind.
If your program is memory-corruption free and you just want to look for memory leaks, you can run your program by prefixing it with "valgrind --leak-check=full" and see what valgrind has found for you. Please understand that, for our programming assignments, there is absolutely no requirement that you don't have memory leaks.
Recently, I have heard about two more memory debuggers.
It's imperative that you backup your code when you are doing a major programming assignment (or even labs). Sometimes, your virtual machine may refuse to start (maybe because of changes in your system) and there is no way to recover files inside the virtual machine. That makes it even more important to backup your code.
Must NOT Use GitHub.Com
You must NOT use GitHub.com because if you don't pay them within a certain time frame, your private repository will automatically become public (no matter what the GitHub.com website says)! Once your code becomes public, future students will be able to copy your code and you will end up helping them to cheat! USC Student Conduct Code (which you have agreed to when you became a student at USC) says that you must not cheat off other students AND you must not knowingly allow other students to cheat off of you. By allowing your code to apper in public, which will perit future students to have access to your code, you are violating the USC Student Conduct Code!
BitBucket is like GitHub.com in that it combines version control and backup. The main difference is that private projects on bitbucket.com stays private.
Use Shared Folder
A quick and easy to to backup is to copy all your files into the shared folder, i.e., the folder you are sharing with the host system. You should make this as easy as possible. Let's say that you put all your code in the folder called cs353 in the home directory of your Ubuntu 16.04 system. Assuming that your shared folder is in /Shared-ubuntu (suggested in the Ubuntu 16.04 installation instruction and additional instructions and you should change it if the location of your shared folder is different). Then you just need to do the following to make a backup. If your command shell is bash, do:cd now=`date +%d%b%Y-%H%M%S` tar cvzf cs353-backup-$now.tar.gz cs353 cp cs353-backup-$now.tar.gz ~/Shared-ubuntu ls -l ~/cs353-backup-$now.tar.gzIf your command shell is tcsh, do:cd set now=`date +%d%b%Y-%H%M%S` tar cvzf cs353-backup-$now.tar.gz cs353 cp cs353-backup-$now.tar.gz ~/Shared-ubuntu ls -l ~/cs353-backup-$now.tar.gzIf you don't know what command shell you are running, do:echo $BASHIf it says that BASH is an undefined variable, then most likely, your command shell is tcsh. Otherwise, your command shell is bash.