2535 lines
No EOL
78 KiB
HTML
2535 lines
No EOL
78 KiB
HTML
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
|
<!-- saved from url=(0058)http://www-users.cs.umn.edu/~kauffman/4061/p2.html#sec-9-1 -->
|
|
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
|
<title>CSCI 4061 Project 2: Blather Chat Server/Client</title>
|
|
<!-- 2017-11-29 Wed 17:46 -->
|
|
|
|
<meta name="generator" content="Org-mode">
|
|
<meta name="author" content="Chris Kauffman">
|
|
<style type="text/css">
|
|
<!--/*--><![CDATA[/*><!--*/
|
|
.title { text-align: center; }
|
|
.todo { font-family: monospace; color: red; }
|
|
.done { color: green; }
|
|
.tag { background-color: #eee; font-family: monospace;
|
|
padding: 2px; font-size: 80%; font-weight: normal; }
|
|
.timestamp { color: #bebebe; }
|
|
.timestamp-kwd { color: #5f9ea0; }
|
|
.right { margin-left: auto; margin-right: 0px; text-align: right; }
|
|
.left { margin-left: 0px; margin-right: auto; text-align: left; }
|
|
.center { margin-left: auto; margin-right: auto; text-align: center; }
|
|
.underline { text-decoration: underline; }
|
|
#postamble p, #preamble p { font-size: 90%; margin: .2em; }
|
|
p.verse { margin-left: 3%; }
|
|
pre {
|
|
border: 1px solid #ccc;
|
|
box-shadow: 3px 3px 3px #eee;
|
|
padding: 8pt;
|
|
font-family: monospace;
|
|
overflow: auto;
|
|
margin: 1.2em;
|
|
}
|
|
pre.src {
|
|
position: relative;
|
|
overflow: visible;
|
|
padding-top: 1.2em;
|
|
}
|
|
pre.src:before {
|
|
display: none;
|
|
position: absolute;
|
|
background-color: white;
|
|
top: -10px;
|
|
right: 10px;
|
|
padding: 3px;
|
|
border: 1px solid black;
|
|
}
|
|
pre.src:hover:before { display: inline;}
|
|
pre.src-sh:before { content: 'sh'; }
|
|
pre.src-bash:before { content: 'sh'; }
|
|
pre.src-emacs-lisp:before { content: 'Emacs Lisp'; }
|
|
pre.src-R:before { content: 'R'; }
|
|
pre.src-perl:before { content: 'Perl'; }
|
|
pre.src-java:before { content: 'Java'; }
|
|
pre.src-sql:before { content: 'SQL'; }
|
|
|
|
table { border-collapse:collapse; }
|
|
caption.t-above { caption-side: top; }
|
|
caption.t-bottom { caption-side: bottom; }
|
|
td, th { vertical-align:top; }
|
|
th.right { text-align: center; }
|
|
th.left { text-align: center; }
|
|
th.center { text-align: center; }
|
|
td.right { text-align: right; }
|
|
td.left { text-align: left; }
|
|
td.center { text-align: center; }
|
|
dt { font-weight: bold; }
|
|
.footpara:nth-child(2) { display: inline; }
|
|
.footpara { display: block; }
|
|
.footdef { margin-bottom: 1em; }
|
|
.figure { padding: 1em; }
|
|
.figure p { text-align: center; }
|
|
.inlinetask {
|
|
padding: 10px;
|
|
border: 2px solid gray;
|
|
margin: 10px;
|
|
background: #ffffcc;
|
|
}
|
|
#org-div-home-and-up
|
|
{ text-align: right; font-size: 70%; white-space: nowrap; }
|
|
textarea { overflow-x: auto; }
|
|
.linenr { font-size: smaller }
|
|
.code-highlighted { background-color: #ffff00; }
|
|
.org-info-js_info-navigation { border-style: none; }
|
|
#org-info-js_console-label
|
|
{ font-size: 10px; font-weight: bold; white-space: nowrap; }
|
|
.org-info-js_search-highlight
|
|
{ background-color: #ffff00; color: #000000; font-weight: bold; }
|
|
/*]]>*/-->
|
|
</style>
|
|
<meta name="viewport" content="width=device-width, maximum-scale=1, minimum-scale=1">
|
|
<style type="text/css">
|
|
@media screen {
|
|
:root {
|
|
--heading-bg-color:#e8c62e;
|
|
--heading-fg-color:#7a0019;
|
|
}
|
|
html {
|
|
font-family: serif;
|
|
text-align: justify;
|
|
}
|
|
pre.src, pre.example {
|
|
overflow-x: scroll;
|
|
}
|
|
/* Merge subtitle area with title area */
|
|
.subtitle {
|
|
text-align: center;
|
|
margin-top: -2em;
|
|
padding-top: 1em;
|
|
padding-bottom: 0.1em;
|
|
}
|
|
.title, .subtitle {
|
|
color: var(--heading-fg-color);
|
|
background-color: var(--heading-bg-color);
|
|
}
|
|
/* Section borders, left section header style */
|
|
div.outline-2, #table-of-contents {
|
|
background-color: rgb(250,250,250);
|
|
border: 0.75em solid var(--heading-bg-color);
|
|
border-top: 0em;
|
|
padding: 0em .5em .5em .5em; /* top right bottom left */
|
|
margin: 1em 0em 1em 0em; /* top right bottom left */
|
|
}
|
|
div.outline-2 > h2, #table-of-contents > h2 {
|
|
background-color: var(--heading-bg-color);
|
|
color: var(--heading-fg-color);
|
|
font-variant: small-caps;
|
|
padding: 0em 0em 0em .5em; /* top right bottom left */
|
|
margin: 0em -.5em 0em -.75em; /* top right bottom left */
|
|
text-align: left;
|
|
}
|
|
blockquote {
|
|
font-style: italic;
|
|
}
|
|
td, th {
|
|
padding-top: 2px;
|
|
padding-bottom: 2px;
|
|
}
|
|
body {
|
|
background-color: #EEE;
|
|
}
|
|
pre {
|
|
}
|
|
#content, #preamble, #postamble {
|
|
margin-left:300px;
|
|
}
|
|
.tag {
|
|
background-color: inherit; font-family: inherit;
|
|
padding: inherit; font-size: 80%; font-weight: inherit;
|
|
text-transform: uppercase;
|
|
}
|
|
.figure p { text-align: inherit; }
|
|
figure-number { font-style: italic; }
|
|
#table-of-contents {
|
|
text-align: left;
|
|
position: fixed;
|
|
left: 0;
|
|
margin: 0 auto;
|
|
padding: 0;
|
|
width: 300px;
|
|
top: 0;
|
|
height: 100%;
|
|
border: 0;
|
|
display: block;
|
|
}
|
|
#text-table-of-contents {
|
|
overflow-y: scroll;
|
|
height: 100%;
|
|
}
|
|
#text-table-of-contents ul {
|
|
padding-left: 1em;
|
|
margin-left: 0.5em;
|
|
}
|
|
#table-of-contents > h2 {
|
|
padding: 0.1em;
|
|
margin: 0;
|
|
}
|
|
/* adjustments for small screen, toc at top only */
|
|
@media (max-width: 800px) { /* landscape for iphone */
|
|
html {
|
|
-webkit-text-size-adjust: none; /* prevent scaling of text on mobile */
|
|
}
|
|
body {
|
|
background-color: #EEE;
|
|
width:100%;
|
|
margin:0 auto;
|
|
}
|
|
#content, #preamble, #postamble {
|
|
margin-left:0;
|
|
}
|
|
#table-of-contents {
|
|
position: static;
|
|
left: inherit;
|
|
width:inherit;
|
|
height: auto;
|
|
border-top: 0em;
|
|
padding: 0em .5em .5em .5em; /* top right bottom left */
|
|
margin: 1em 0em 1em 0em; /* top right bottom left */
|
|
border: 0.75em solid #006633;
|
|
}
|
|
div.outline-2, #table-of-contents {
|
|
background-color: rgb(250,250,250);
|
|
border: 0.75em solid var(--heading-bg-color);
|
|
border-top: 0em;
|
|
padding: 0em .5em .5em .5em; /* top right bottom left */
|
|
margin: 1em 0em 1em 0em; /* top right bottom left */
|
|
}
|
|
div.outline-2 > h2, #table-of-contents > h2 {
|
|
background-color: var(--heading-bg-color);
|
|
color: var(--heading-fg-color);
|
|
font-variant: small-caps;
|
|
padding: 0em 0em 0em .5em; /* top right bottom left */
|
|
margin: 0em -.5em 0em -.75em; /* top right bottom left */
|
|
text-align: left;
|
|
}
|
|
#text-table-of-contents {
|
|
overflow-y: visible;
|
|
height: inherit;
|
|
}
|
|
#text-table-of-contents ul {
|
|
padding-left: 1em;
|
|
margin-left: 0.5em;
|
|
}
|
|
}
|
|
.linenr { font-size: xx-small; }
|
|
}
|
|
@media print {
|
|
html {
|
|
font-family: serif;
|
|
font-size: 10pt;
|
|
text-align: justify;
|
|
.linenr { font-size: xx-small; }
|
|
}
|
|
}
|
|
</style>
|
|
<script type="text/javascript">
|
|
/*
|
|
@licstart The following is the entire license notice for the
|
|
JavaScript code in this tag.
|
|
|
|
Copyright (C) 2012-2013 Free Software Foundation, Inc.
|
|
|
|
The JavaScript code in this tag is free software: you can
|
|
redistribute it and/or modify it under the terms of the GNU
|
|
General Public License (GNU GPL) as published by the Free Software
|
|
Foundation, either version 3 of the License, or (at your option)
|
|
any later version. The code is distributed WITHOUT ANY WARRANTY;
|
|
without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.
|
|
|
|
As additional permission under GNU GPL version 3 section 7, you
|
|
may distribute non-source (e.g., minimized or compacted) forms of
|
|
that code without the copy of the GNU GPL normally required by
|
|
section 4, provided you include this license notice and a URL
|
|
through which recipients can access the Corresponding Source.
|
|
|
|
|
|
@licend The above is the entire license notice
|
|
for the JavaScript code in this tag.
|
|
*/
|
|
<!--/*--><![CDATA[/*><!--*/
|
|
function CodeHighlightOn(elem, id)
|
|
{
|
|
var target = document.getElementById(id);
|
|
if(null != target) {
|
|
elem.cacheClassElem = elem.className;
|
|
elem.cacheClassTarget = target.className;
|
|
target.className = "code-highlighted";
|
|
elem.className = "code-highlighted";
|
|
}
|
|
}
|
|
function CodeHighlightOff(elem, id)
|
|
{
|
|
var target = document.getElementById(id);
|
|
if(elem.cacheClassElem)
|
|
elem.className = elem.cacheClassElem;
|
|
if(elem.cacheClassTarget)
|
|
target.className = elem.cacheClassTarget;
|
|
}
|
|
/*]]>*///-->
|
|
</script>
|
|
<style>#cVim-command-bar, #cVim-command-bar-mode, #cVim-command-bar-input, #cVim-command-bar-search-results,
|
|
.cVim-completion-item, .cVim-completion-item .cVim-full, .cVim-completion-item .cVim-left,
|
|
.cVim-completion-item .cVim-right {
|
|
font-family: Helvetica, Helvetica Neue, Neue, sans-serif, monospace, Arial;
|
|
font-size: 10pt !important;
|
|
-webkit-font-smoothing: antialiased !important;
|
|
}
|
|
|
|
#cVim-command-bar {
|
|
position: fixed;
|
|
z-index: 2147483646;
|
|
background-color: #1b1d1e;
|
|
color: #bbb;
|
|
display: none;
|
|
box-sizing: content-box;
|
|
box-shadow: 0 3px 3px rgba(0,0,0,0.4);
|
|
left: 0;
|
|
width: 100%;
|
|
height: 20px;
|
|
}
|
|
|
|
#cVim-command-bar-mode {
|
|
display: inline-block;
|
|
vertical-align: middle;
|
|
box-sizing: border-box;
|
|
padding-left: 2px;
|
|
height: 100%;
|
|
width: 10px;
|
|
padding-top: 2px;
|
|
color: #888;
|
|
}
|
|
|
|
#cVim-command-bar-input {
|
|
background-color: #1b1d1e;
|
|
color: #bbb;
|
|
height: 100%;
|
|
right: 0;
|
|
top: 0;
|
|
width: calc(100% - 10px);
|
|
position: absolute;
|
|
}
|
|
|
|
#cVim-command-bar-search-results {
|
|
position: fixed;
|
|
width: 100%;
|
|
overflow: hidden;
|
|
z-index: 2147483647;
|
|
left: 0;
|
|
box-shadow: 0 3px 3px rgba(0,0,0,0.4);
|
|
background-color: #1c1c1c;
|
|
}
|
|
|
|
.cVim-completion-item, .cVim-completion-item .cVim-full, .cVim-completion-item .cVim-left, .cVim-completion-item .cVim-right {
|
|
text-overflow: ellipsis;
|
|
padding: 1px;
|
|
display: inline-block;
|
|
box-sizing: border-box;
|
|
vertical-align: middle;
|
|
overflow: hidden;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.cVim-completion-item:nth-child(even) {
|
|
background-color: #1f1f1f;
|
|
}
|
|
|
|
.cVim-completion-item {
|
|
width: 100%; left: 0;
|
|
color: #bcbcbc;
|
|
}
|
|
|
|
.cVim-completion-item[active] {
|
|
width: 100%; left: 0;
|
|
color: #1b1d1e;
|
|
background-color: #f1f1f1;
|
|
}
|
|
|
|
.cVim-completion-item[active] span {
|
|
color: #1b1d1e;
|
|
}
|
|
|
|
.cVim-completion-item .cVim-left {
|
|
color: #fff;
|
|
width: 37%;
|
|
}
|
|
|
|
.cVim-completion-item .cVim-right {
|
|
font-style: italic;
|
|
color: #888;
|
|
width: 57%;
|
|
}
|
|
|
|
|
|
#cVim-link-container, .cVim-link-hint,
|
|
#cVim-hud, #cVim-status-bar {
|
|
font-family: Helvetica, Helvetica Neue, Neue, sans-serif, monospace, Arial;
|
|
font-size: 10pt !important;
|
|
-webkit-font-smoothing: antialiased !important;
|
|
}
|
|
|
|
#cVim-link-container {
|
|
position: absolute;
|
|
pointer-events: none;
|
|
width: 100%; left: 0;
|
|
height: 100%; top: 0;
|
|
z-index: 2147483647;
|
|
}
|
|
|
|
.cVim-link-hint {
|
|
position: absolute;
|
|
color: #302505 !important;
|
|
background-color: #ffd76e !important;
|
|
border-radius: 2px !important;
|
|
padding: 2px !important;
|
|
font-size: 8pt !important;
|
|
font-weight: 500 !important;
|
|
text-transform: uppercase !important;
|
|
border: 1px solid #ad810c;
|
|
display: inline-block !important;
|
|
vertical-align: middle !important;
|
|
text-align: center !important;
|
|
box-shadow: 2px 2px 1px rgba(0,0,0,0.25) !important;
|
|
}
|
|
|
|
.cVim-link-hint_match {
|
|
color: #777;
|
|
text-transform: uppercase !important;
|
|
}
|
|
|
|
|
|
#cVim-hud {
|
|
background-color: rgba(28,28,28,0.9);
|
|
position: fixed !important;
|
|
transition: right 0.2s ease-out;
|
|
z-index: 24724289;
|
|
}
|
|
|
|
#cVim-hud span {
|
|
padding: 2px;
|
|
padding-left: 4px;
|
|
padding-right: 4px;
|
|
color: #8f8f8f;
|
|
font-size: 10pt;
|
|
}
|
|
|
|
#cVim-frames-outline {
|
|
position: fixed;
|
|
width: 100%;
|
|
height: 100%;
|
|
left: 0;
|
|
top: 0;
|
|
right: 0;
|
|
z-index: 9999999999;
|
|
box-sizing: border-box;
|
|
border: 3px solid yellow;
|
|
}
|
|
</style></head>
|
|
<body>
|
|
<div id="preamble" class="status">
|
|
<i>Last Updated: 2017-11-29 Wed 17:46</i>
|
|
</div>
|
|
<div id="content">
|
|
<h1 class="title">CSCI 4061 Project 2: Blather Chat Server/Client</h1>
|
|
<ul class="org-ul">
|
|
<li><b>Due: 11:59pm Tue 12/12/2017</b>
|
|
</li>
|
|
<li><i>Approximately 20.0% of total grade</i>
|
|
</li>
|
|
<li>Submit to <a href="https://canvas.umn.edu/"><b>Canvas</b></a>
|
|
</li>
|
|
<li>Projects may be done in groups of 1 or 2. Indicate groups in the
|
|
<code>GROUP-MEMBERS.txt</code> file.
|
|
</li>
|
|
<li>No additional collaboration with other students is allowed. Seek
|
|
help from course staff if you get stuck for too long.
|
|
</li>
|
|
</ul>
|
|
|
|
<div id="outline-container-sec-0-0-1" class="outline-4">
|
|
<h4 id="sec-0-0-1">CODE DISTRIBUTION: <a href="http://www-users.cs.umn.edu/~kauffman/4061/p2-code.zip">p2-code.zip</a></h4>
|
|
</div>
|
|
<div id="outline-container-sec-0-0-2" class="outline-4">
|
|
<h4 id="sec-0-0-2">TEST CODE: <i>Not posted</i></h4>
|
|
<div class="outline-text-4" id="text-0-0-2">
|
|
</div>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-0-0-3" class="outline-4">
|
|
<h4 id="sec-0-0-3">CHANGELOG:</h4>
|
|
<div class="outline-text-4" id="text-0-0-3">
|
|
<dl class="org-dl">
|
|
<dt> Tue Nov 28 15:33:01 CST 2017 </dt><dd> Corrected project weight. Re-ordered to put optional ADVANCED
|
|
features at end. Described unlinking the semaphore for final
|
|
ADVANCED feature.
|
|
</dd>
|
|
</dl>
|
|
|
|
<div id="table-of-contents">
|
|
<h2>Table of Contents</h2>
|
|
<div id="text-table-of-contents">
|
|
<ul>
|
|
<li><a href="http://www-users.cs.umn.edu/~kauffman/4061/p2.html#sec-1">1. Introduction: A Chat Service</a>
|
|
<ul>
|
|
<li><a href="http://www-users.cs.umn.edu/~kauffman/4061/p2.html#sec-1-1">1.1. Basic Features</a></li>
|
|
<li><a href="http://www-users.cs.umn.edu/~kauffman/4061/p2.html#sec-1-2">1.2. ADVANCED Features : Extra Credit</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="http://www-users.cs.umn.edu/~kauffman/4061/p2.html#sec-2">2. Download Code and Setup</a></li>
|
|
<li><a href="http://www-users.cs.umn.edu/~kauffman/4061/p2.html#sec-3">3. Demo / ScreenShot</a></li>
|
|
<li><a href="http://www-users.cs.umn.edu/~kauffman/4061/p2.html#sec-4">4. Overall Architecture</a>
|
|
<ul>
|
|
<li><a href="http://www-users.cs.umn.edu/~kauffman/4061/p2.html#sec-4-1">4.1. What Needs to be Implemented</a></li>
|
|
<li><a href="http://www-users.cs.umn.edu/~kauffman/4061/p2.html#sec-4-2">4.2. What's Already Done</a></li>
|
|
<li><a href="http://www-users.cs.umn.edu/~kauffman/4061/p2.html#sec-4-3">4.3. Provide a Makefile</a></li>
|
|
<li><a href="http://www-users.cs.umn.edu/~kauffman/4061/p2.html#sec-4-4">4.4. No malloc() / free() required</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="http://www-users.cs.umn.edu/~kauffman/4061/p2.html#sec-5">5. Basic Protocol and Architecture</a>
|
|
<ul>
|
|
<li><a href="http://www-users.cs.umn.edu/~kauffman/4061/p2.html#sec-5-1">5.1. Server and Clients</a></li>
|
|
<li><a href="http://www-users.cs.umn.edu/~kauffman/4061/p2.html#sec-5-2">5.2. Joining</a></li>
|
|
<li><a href="http://www-users.cs.umn.edu/~kauffman/4061/p2.html#sec-5-3">5.3. Normal Messages</a></li>
|
|
<li><a href="http://www-users.cs.umn.edu/~kauffman/4061/p2.html#sec-5-4">5.4. Departures and Removing Clients</a></li>
|
|
<li><a href="http://www-users.cs.umn.edu/~kauffman/4061/p2.html#sec-5-5">5.5. Protocol Data Types</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="http://www-users.cs.umn.edu/~kauffman/4061/p2.html#sec-6">6. The Server</a>
|
|
<ul>
|
|
<li><a href="http://www-users.cs.umn.edu/~kauffman/4061/p2.html#sec-6-1">6.1. Server and Client Data</a></li>
|
|
<li><a href="http://www-users.cs.umn.edu/~kauffman/4061/p2.html#sec-6-2">6.2. Server Operations: <code>server.c</code></a></li>
|
|
<li><a href="http://www-users.cs.umn.edu/~kauffman/4061/p2.html#sec-6-3">6.3. Messages Handled by the Server</a></li>
|
|
<li><a href="http://www-users.cs.umn.edu/~kauffman/4061/p2.html#sec-6-4">6.4. Other Messages Sent by the Server</a></li>
|
|
<li><a href="http://www-users.cs.umn.edu/~kauffman/4061/p2.html#sec-6-5">6.5. <code>bl-server.c</code> main function</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="http://www-users.cs.umn.edu/~kauffman/4061/p2.html#sec-7">7. The Client</a>
|
|
<ul>
|
|
<li><a href="http://www-users.cs.umn.edu/~kauffman/4061/p2.html#sec-7-1">7.1. Simplified Terminal I/O</a></li>
|
|
<li><a href="http://www-users.cs.umn.edu/~kauffman/4061/p2.html#sec-7-2">7.2. <code>bl-client.c</code> Features</a></li>
|
|
<li><a href="http://www-users.cs.umn.edu/~kauffman/4061/p2.html#sec-7-3">7.3. Client Main Approach</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="http://www-users.cs.umn.edu/~kauffman/4061/p2.html#sec-8">8. Manual Inspection Criteria (50%)</a></li>
|
|
<li><a href="http://www-users.cs.umn.edu/~kauffman/4061/p2.html#sec-9">9. ADVANCED Features</a>
|
|
<ul>
|
|
<li><a href="http://www-users.cs.umn.edu/~kauffman/4061/p2.html#sec-9-1">9.1. Server Ping and Disconnected Clients (10%)</a></li>
|
|
<li><a href="http://www-users.cs.umn.edu/~kauffman/4061/p2.html#sec-9-2">9.2. Binary Server Log File (10%)</a></li>
|
|
<li><a href="http://www-users.cs.umn.edu/~kauffman/4061/p2.html#sec-9-3">9.3. Last Messages for Client (10%)</a></li>
|
|
<li><a href="http://www-users.cs.umn.edu/~kauffman/4061/p2.html#sec-9-4">9.4. <code>who_t</code> for Client and Server (10%)</a></li>
|
|
</ul>
|
|
</li>
|
|
<li><a href="http://www-users.cs.umn.edu/~kauffman/4061/p2.html#sec-10">10. Automatic Testing (50%)</a></li>
|
|
<li><a href="http://www-users.cs.umn.edu/~kauffman/4061/p2.html#sec-11">11. Zip and Submit</a>
|
|
<ul>
|
|
<li><a href="http://www-users.cs.umn.edu/~kauffman/4061/p2.html#sec-11-1">11.1. Submit to Canvas</a></li>
|
|
<li><a href="http://www-users.cs.umn.edu/~kauffman/4061/p2.html#sec-11-2">11.2. Late Policies</a></li>
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-1" class="outline-2">
|
|
<h2 id="sec-1"><span class="section-number-2">1</span> Introduction: A Chat Service</h2>
|
|
<div class="outline-text-2" id="text-1">
|
|
<p>
|
|
Systems programming is often associated with communication as this
|
|
invariably requires coordinating multiple entities that are related
|
|
only based on their desire to share information. This project focuses
|
|
on developing a simple <b>chat server and client</b> called <code>blather</code>. The
|
|
basic usage is in two parts.
|
|
</p>
|
|
<dl class="org-dl">
|
|
<dt> Server </dt><dd> Some user starts <code>bl-server</code> which manages the chat "room". The
|
|
server is non-interactive and will likely only print debugging
|
|
output as it runs.
|
|
</dd>
|
|
<dt> Client </dt><dd> Any user who wishes to chat runs <code>bl-client</code> which takes input
|
|
typed on the keyboard and sends it to the server. The server
|
|
broadcasts the input to all other clients who can respond by
|
|
typing their own input.
|
|
</dd>
|
|
</dl>
|
|
|
|
<p>
|
|
Chat servers are an old idea dating to the late 1970's and if you have
|
|
never used one previously, get online a bit more or <a href="https://en.wikipedia.org/wiki/Online_chat">read about them on
|
|
Wikipedia</a>. Even standard Unix terminals have a built-in ability to
|
|
communicate with other users through <a href="http://man7.org/linux/man-pages/man1/mesg.1.html">commands like <code>write</code>, <code>wall</code>,
|
|
and <code>talk</code></a>.
|
|
</p>
|
|
|
|
<p>
|
|
Unlike standard internet chat services, <code>blather</code> will be restricted
|
|
to a single Unix machine and to users with permission to read related
|
|
files. However, extending the programs to run via the internet will
|
|
be the subject of some discussion.
|
|
</p>
|
|
|
|
<p>
|
|
Like most interesting projects, <code>blather</code> utilizes a combination of
|
|
many different system tools. Look for the following items to arise.
|
|
</p>
|
|
<ul class="org-ul">
|
|
<li>Multiple communicating processes: clients to servers
|
|
</li>
|
|
<li>Communication through FIFOs
|
|
</li>
|
|
<li>Signal handling for graceful server shutdown
|
|
</li>
|
|
<li>Alarm signals for periodic behavior
|
|
</li>
|
|
<li>Input multiplexing with <code>select()</code>
|
|
</li>
|
|
<li>Multiple threads in the client to handle typed input versus info
|
|
from the server
|
|
</li>
|
|
</ul>
|
|
|
|
<p>
|
|
Finally, this project includes some <b>advanced features</b> which may be
|
|
implemented for extra credit.
|
|
</p>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-1-1" class="outline-3">
|
|
<h3 id="sec-1-1"><span class="section-number-3">1.1</span> Basic Features</h3>
|
|
<div class="outline-text-3" id="text-1-1">
|
|
<p>
|
|
The specification below is mainly concerned with basic features of the
|
|
<code>blather</code> server and client. Implementing these can garner full credit
|
|
for the assignment.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-1-2" class="outline-3">
|
|
<h3 id="sec-1-2"><span class="section-number-3">1.2</span> ADVANCED Features : Extra Credit</h3>
|
|
<div class="outline-text-3" id="text-1-2">
|
|
<p>
|
|
Some portions of the specification and code are marked ADVANCED to
|
|
indicate optional features that can be implemented for extra
|
|
credit. Some of these have dependencies so take care to read
|
|
carefully.
|
|
</p>
|
|
|
|
<p>
|
|
ADVANCED features may be evaluated using tests and manual inspection
|
|
criteria that are made available after the standard tests are
|
|
distributed.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-2" class="outline-2">
|
|
<h2 id="sec-2"><span class="section-number-2">2</span> Download Code and Setup</h2>
|
|
<div class="outline-text-2" id="text-2">
|
|
<p>
|
|
As in labs, download the code pack linked at the top of the
|
|
page. Unzip this which will create a folder and create your files in
|
|
that folder.
|
|
</p>
|
|
|
|
<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
|
|
|
|
|
|
<colgroup>
|
|
<col class="left">
|
|
|
|
<col class="left">
|
|
|
|
<col class="left">
|
|
</colgroup>
|
|
<thead>
|
|
<tr>
|
|
<th scope="col" class="left">File</th>
|
|
<th scope="col" class="left">State</th>
|
|
<th scope="col" class="left">Notes</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td class="left">GROUP-MEMBERS.txt</td>
|
|
<td class="left">Edit</td>
|
|
<td class="left">Fill in names of group members to indicate partnerships</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="left">Makefile</td>
|
|
<td class="left">Create</td>
|
|
<td class="left">Build project, run tests</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="left">server.c</td>
|
|
<td class="left">Create</td>
|
|
<td class="left">Service routines for the server</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="left">bl-server.c</td>
|
|
<td class="left">Create</td>
|
|
<td class="left">Main function for <code>bl-server</code> executable</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="left">bl-client.c</td>
|
|
<td class="left">Create</td>
|
|
<td class="left">Main function for <code>bl-client</code> executable</td>
|
|
</tr>
|
|
</tbody>
|
|
<tbody>
|
|
<tr>
|
|
<td class="left">blather.h</td>
|
|
<td class="left">Provided</td>
|
|
<td class="left">Header file which contains required structs, defines, and prototypes</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="left">util.c</td>
|
|
<td class="left">Provided</td>
|
|
<td class="left">Utility methods debug messages and checking system call returns</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="left">simpio.c</td>
|
|
<td class="left">Provided</td>
|
|
<td class="left">Simplified terminal I/O to get nice interactive sessions</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="left">simpio-demo.c</td>
|
|
<td class="left">Provided</td>
|
|
<td class="left">Demonstrates simpio features, model for <code>bl-client.c</code></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<div id="outline-container-sec-3" class="outline-2">
|
|
<h2 id="sec-3"><span class="section-number-2">3</span> Demo / ScreenShot</h2>
|
|
<div class="outline-text-2" id="text-3">
|
|
<p>
|
|
Demonstrating an interactive, dynamic chat session between multiple
|
|
users is difficult but the screenshot below attempts to do so. It
|
|
shows the server and several clients mid-chat.
|
|
</p>
|
|
<ul class="org-ul">
|
|
<li>The server <code>bl-server</code> is started in the large terminal on the left
|
|
and shows output about what is going on. There is no specific output
|
|
required and that shown is for debugging purposes.
|
|
</li>
|
|
<li>There are 4 <code>bl-client</code> instances run by various users who log into
|
|
the server and specify their name. The lower-right user <code>Barbara</code>
|
|
joins later while the upper left user <code>Bruce</code> logs out near the end
|
|
of the session.
|
|
</li>
|
|
</ul>
|
|
|
|
<div class="center">
|
|
|
|
<div class="figure">
|
|
<p><img src="./readme_files/blather-demo.png" alt="blather-demo.png" width="100%" style="max-width:100%;">
|
|
</p>
|
|
<p><span class="figure-number">Figure 1:</span> Sample <code>blather</code> server and client runs.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-4" class="outline-2">
|
|
<h2 id="sec-4"><span class="section-number-2">4</span> Overall Architecture</h2>
|
|
<div class="outline-text-2" id="text-4">
|
|
</div><div id="outline-container-sec-4-1" class="outline-3">
|
|
<h3 id="sec-4-1"><span class="section-number-3">4.1</span> What Needs to be Implemented</h3>
|
|
<div class="outline-text-3" id="text-4-1">
|
|
<p>
|
|
<code>blather</code> has two parts: the server and client. Both need to be
|
|
written along with service routines in <code>server.c</code>
|
|
</p>
|
|
</div>
|
|
<div id="outline-container-sec-4-1-1" class="outline-4">
|
|
<h4 id="sec-4-1-1"><code>server.c</code> data structure manipulations</h4>
|
|
<div class="outline-text-4" id="text-4-1-1">
|
|
<p>
|
|
Implement the functions in this file to manipulate the <code>server_t</code> and
|
|
<code>client_t</code> data that will ultimately be used by the server to fulfill
|
|
its role.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-4-1-2" class="outline-4">
|
|
<h4 id="sec-4-1-2"><code>bl-server.c</code> main function and signal handlers</h4>
|
|
<div class="outline-text-4" id="text-4-1-2">
|
|
<p>
|
|
Implement the server which manages the interactions between clients in
|
|
this file making use of the service functions in <code>server.c</code> to get the
|
|
job done.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-4-1-3" class="outline-4">
|
|
<h4 id="sec-4-1-3"><code>bl-client.c</code> main function and thread workers</h4>
|
|
<div class="outline-text-4" id="text-4-1-3">
|
|
<p>
|
|
Implement the client which allows a single user to communicate with
|
|
the server in this file. The client must have multiple threads so you
|
|
will need to implement some worker functions as thread entry points
|
|
here.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-4-2" class="outline-3">
|
|
<h3 id="sec-4-2"><span class="section-number-3">4.2</span> What's Already Done</h3>
|
|
<div class="outline-text-3" id="text-4-2">
|
|
<p>
|
|
Examine the provided files closely as they give some insight into what
|
|
work is already done.
|
|
</p>
|
|
<ul class="org-ul">
|
|
<li><code>blather.h</code> can be included in most files to make programs aware of
|
|
the data structures and required functions. It contains
|
|
documentation of the central data structures.
|
|
</li>
|
|
<li><code>util.c</code> contains a few functions for debugging and checking system
|
|
calls.
|
|
</li>
|
|
<li><code>simpio.c</code> and <code>simpio-demo.c</code> provide a small library and data
|
|
structure to do terminal I/O nicely. The demo program shows how it
|
|
works.
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-4-3" class="outline-3">
|
|
<h3 id="sec-4-3"><span class="section-number-3">4.3</span> Provide a Makefile</h3>
|
|
<div class="outline-text-3" id="text-4-3">
|
|
<p>
|
|
Provide a <code>Makefile</code> which has at least the following targets.
|
|
</p>
|
|
<ul class="org-ul">
|
|
<li><code>bl-server</code> : builds the server executable, be included in the
|
|
default targets.
|
|
</li>
|
|
<li><code>bl-client</code> : builds the client executable, be included in the
|
|
default targets.
|
|
</li>
|
|
<li><code>test-binary</code> : compile and run the binary tests
|
|
</li>
|
|
<li><code>test-shell</code> : run the shell scripts associated with integration
|
|
tests
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-4-4" class="outline-3">
|
|
<h3 id="sec-4-4"><span class="section-number-3">4.4</span> No malloc() / free() required</h3>
|
|
<div class="outline-text-3" id="text-4-4">
|
|
<p>
|
|
It may come as a surprise, but this set of programs is specifically
|
|
oriented so that no dynamic memory allocation is required. All of the
|
|
data structures are fixed size, strings have a maximum length, and
|
|
communication is done through FIFOs. Keep this in mind as you code
|
|
and avoid <code>malloc()</code> unless you see no other way around it as it will
|
|
likely make things harder than they need to be.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<div id="outline-container-sec-5" class="outline-2">
|
|
<h2 id="sec-5"><span class="section-number-2">5</span> Basic Protocol and Architecture</h2>
|
|
<div class="outline-text-2" id="text-5">
|
|
<p>
|
|
Clients communicate with the server along the following lines.
|
|
</p>
|
|
<ul class="org-ul">
|
|
<li><code>bl-server</code> creates a FIFO at startup time. The FIFO is created with
|
|
a name specified according to naming convention at startup. Examples:
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-sh">$> bl-server server1 # creates the server1.fifo
|
|
$> bl-server batcave # creates the batcave.fifo
|
|
$> bl-server fortress-of-solitude # creates the fortress-of-solitude.fifo
|
|
</pre>
|
|
</div>
|
|
<p>
|
|
This FIFO is <b>only for join requests</b> to the server. The name of
|
|
this file must be known for the clients to connect to server.
|
|
</p>
|
|
</li>
|
|
<li>The server then waits for clients to write join requests to join
|
|
FIFO.
|
|
</li>
|
|
<li><code>bl-client</code> creates two FIFOs on startup:
|
|
<ul class="org-ul">
|
|
<li>A <b>to-client FIFO</b> for the server to write data intended for the
|
|
client. The client reads this FIFO.
|
|
</li>
|
|
<li>A <b>to-server FIFO</b> to which the client writes and from which the
|
|
server reads.
|
|
</li>
|
|
<li>The names of these files are inconsequential so long as they are
|
|
fairly unique. Basing names for the FIFOs on the PID of the client
|
|
is an easy way to do this. This avoids multiple clients in the
|
|
same directory mistakenly using each other's FIFOs.
|
|
</li>
|
|
</ul>
|
|
</li>
|
|
<li>A client writes a join request to the server which includes the
|
|
names of its to-client and to-server FIFOs. All subsequent
|
|
communication between client and server is done through the
|
|
to-client and to-server FIFOs.
|
|
</li>
|
|
<li>A client reads typed input from users. When input is ready, it is
|
|
sent as a <b>mesg<sub>t</sub></b> to the server.
|
|
</li>
|
|
<li>As a server receives messages from clients, it will <b>broadcast</b> the
|
|
message to all clients including the sender.
|
|
</li>
|
|
<li>The server sends notices of other kinds to the clients such as when
|
|
a new client <b>joins</b>. Clients may send <b>departure</b> notices which are
|
|
re-broadcast by the server.
|
|
</li>
|
|
</ul>
|
|
|
|
<p>
|
|
The sections below give graphical depictions of some of the ideas of
|
|
the protocols.
|
|
</p>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-5-1" class="outline-3">
|
|
<h3 id="sec-5-1"><span class="section-number-3">5.1</span> Server and Clients</h3>
|
|
<div class="outline-text-3" id="text-5-1">
|
|
<p>
|
|
The following diagram illustrates the single server <code>server1</code> with 2
|
|
clients connected. Each client has its own FIFOs for communication
|
|
with the server and the server knows about these FIFOs.
|
|
</p>
|
|
<div class="center">
|
|
|
|
<div class="figure">
|
|
<p><img src="./readme_files/schematic.svg" alt="schematic.svg" width="50%" style="max-width:100%;">
|
|
</p>
|
|
<p><span class="figure-number">Figure 2:</span> Schematic of server data which has been joined by 2 clients.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-5-2" class="outline-3">
|
|
<h3 id="sec-5-2"><span class="section-number-3">5.2</span> Joining</h3>
|
|
<div class="outline-text-3" id="text-5-2">
|
|
<p>
|
|
This diagram illustrates how a new client can join the server. It
|
|
creates FIFOs for communication and then writes a <code>join_t</code> request on
|
|
the server's FIFO. The server then adds the client information to its
|
|
array and broadcasts the join to all clients.
|
|
</p>
|
|
|
|
<div class="center">
|
|
|
|
<div class="figure">
|
|
<p><img src="./readme_files/join-request.svg" alt="join-request.svg" width="100%" style="max-width:100%;">
|
|
</p>
|
|
<p><span class="figure-number">Figure 3:</span> New client joining the server which has two existing clients.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-5-3" class="outline-3">
|
|
<h3 id="sec-5-3"><span class="section-number-3">5.3</span> Normal Messages</h3>
|
|
<div class="outline-text-3" id="text-5-3">
|
|
<p>
|
|
A client wanting to communicate with others sends a normal <code>mesg_t</code> to
|
|
the server with its name and body filled in. The client's to-server
|
|
FIFO is used for this. The server then broadcasts the same message to
|
|
all clients including the sender.
|
|
</p>
|
|
|
|
<div class="center">
|
|
|
|
<div class="figure">
|
|
<p><img src="./readme_files/broadcast.svg" alt="broadcast.svg" width="100%" style="max-width:100%;">
|
|
</p>
|
|
<p><span class="figure-number">Figure 4:</span> Client sending a message which is broadcast to all other clients.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-5-4" class="outline-3">
|
|
<h3 id="sec-5-4"><span class="section-number-3">5.4</span> Departures and Removing Clients</h3>
|
|
<div class="outline-text-3" id="text-5-4">
|
|
<p>
|
|
A client can indicate it is leaving by sending an appropriate
|
|
message. The server will remove its FIFOs and shift all elements in
|
|
its clients array. The departure is broadcast to all clients.
|
|
</p>
|
|
|
|
<div class="center">
|
|
|
|
<div class="figure">
|
|
<p><img src="./readme_files/depart.svg" alt="depart.svg" width="100%" style="max-width:100%;">
|
|
</p>
|
|
<p><span class="figure-number">Figure 5:</span> Client sending a message which is broadcast to all other clients.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-5-5" class="outline-3">
|
|
<h3 id="sec-5-5"><span class="section-number-3">5.5</span> Protocol Data Types</h3>
|
|
<div class="outline-text-3" id="text-5-5">
|
|
<p>
|
|
The header file <code>blather.h</code> describes several data types associated
|
|
with basic communication operations. One of these is the <code>mesg_t</code>
|
|
struct which is used to convey information between clients and server.
|
|
</p>
|
|
<pre class="example">// mesg_t: struct for messages between server/client
|
|
typedef struct {
|
|
mesg_kind_t kind; // kind of message
|
|
char name[MAXNAME]; // name of sending client or subject of event
|
|
char body[MAXLINE]; // body text, possibly empty depending on kind
|
|
} mesg_t;
|
|
</pre>
|
|
|
|
<p>
|
|
Each message has a <b>kind</b> which helps determine what to do with the
|
|
messages. The kinds are defined in the <code>mesg_kind_t</code> enumeration which
|
|
sets up specific integers associated with each kind.
|
|
</p>
|
|
<pre class="example">// mesg_kind_t: Kinds of messages between server/client
|
|
typedef enum {
|
|
BL_MESG = 10, // normal messasge from client with name/body
|
|
BL_JOINED = 20, // client joined the server, name only
|
|
BL_DEPARTED = 30, // client leaving/left server normally, name only
|
|
BL_SHUTDOWN = 40, // server to client : server is shutting down, no name/body
|
|
BL_DISCONNECTED = 50, // ADVANCED: client disconnected abnormally, name only
|
|
BL_PING = 60, // ADVANCED: ping to ask or show liveness
|
|
} mesg_kind_t;
|
|
</pre>
|
|
|
|
<p>
|
|
Messages are sent both from client to server and from server to client
|
|
through the FIFOs that connect them. The specification below will
|
|
describe what actions need be taken on receiving messages.
|
|
</p>
|
|
|
|
<p>
|
|
Finally, when the a client wishes to initially join the server, it
|
|
fills in and sends a <code>join_t</code>.
|
|
</p>
|
|
<pre class="example">// join_t: structure for requests to join the chat room
|
|
typedef struct {
|
|
char name[MAXPATH]; // name of the client joining the server
|
|
char to_client_fname[MAXPATH]; // name of file server writes to to send to client
|
|
char to_server_fname[MAXPATH]; // name of file client writes to to send to server
|
|
} join_t;
|
|
</pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<div id="outline-container-sec-6" class="outline-2">
|
|
<h2 id="sec-6"><span class="section-number-2">6</span> The Server</h2>
|
|
<div class="outline-text-2" id="text-6">
|
|
<p>
|
|
The <code>bl-server.c</code> program is responsible for allowing clients to
|
|
connect, become aware of one another, and communicate. It's main
|
|
functionality is to <b>broadcast</b> messages from one client to all others
|
|
and to broadcast status changes such as new clients that join or
|
|
depart.
|
|
</p>
|
|
</div>
|
|
|
|
|
|
<div id="outline-container-sec-6-1" class="outline-3">
|
|
<h3 id="sec-6-1"><span class="section-number-3">6.1</span> Server and Client Data</h3>
|
|
<div class="outline-text-3" id="text-6-1">
|
|
<p>
|
|
To that end, the server process should maintain a <code>server_t</code> data
|
|
structure which is defined in <code>blather.h</code> as below
|
|
</p>
|
|
|
|
<pre class="example">// server_t: data pertaining to server operations
|
|
typedef struct {
|
|
char server_name[MAXPATH]; // name of server which dictates file names for joining and logging
|
|
int join_fd; // file descriptor of join file/FIFO
|
|
int join_ready; // flag indicating if a join is available
|
|
int n_clients; // number of clients communicating with server
|
|
client_t client[MAXCLIENTS]; // array of clients populated up to n_clients
|
|
int time_sec; // ADVANCED: time in seconds since server started
|
|
int log_fd; // ADVANCED: file descriptor for log
|
|
sem_t *log_sem; // ADVANCED: posix semaphore to control who_t section of log file
|
|
} server_t;
|
|
</pre>
|
|
|
|
<p>
|
|
The most prominent features of this structure are as follows.
|
|
</p>
|
|
<ul class="org-ul">
|
|
<li>The <code>server_name</code> which determines the name of the FIFO filename for
|
|
joining and a few other things.
|
|
</li>
|
|
<li>A <code>join_fd</code> file descriptor which should be attached to a FIFO to
|
|
read requests from clients to join the server.
|
|
</li>
|
|
<li>The <code>client[][</code> array of <code>client_t</code> structs that track clients
|
|
connected to the server. The field <code>n_clients</code> determines how full
|
|
this array is.
|
|
</li>
|
|
</ul>
|
|
|
|
<p>
|
|
Associated closely with the <code>server_t</code> is the <code>client_t</code> struct which
|
|
contains data on each client.
|
|
</p>
|
|
<pre class="example">// client_t: data on a client connected to the server
|
|
typedef struct {
|
|
char name[MAXPATH]; // name of the client
|
|
int to_client_fd; // file descriptor to write to to send to client
|
|
int to_server_fd; // file descriptor to read from to receive from client
|
|
char to_client_fname[MAXPATH]; // name of file (FIFO) to write into send to client
|
|
char to_server_fname[MAXPATH]; // name of file (FIFO) to read from receive from client
|
|
int data_ready; // flag indicating a mesg_t can be read from to_server_fd
|
|
int last_contact_time; // ADVANCED: server time at which last contact was made with client
|
|
} client_t;
|
|
</pre>
|
|
|
|
<p>
|
|
While the client program <code>bl-client</code> may make use of this struct as
|
|
well its main purpose is to help track data for the server. Prominent
|
|
features are as follows.
|
|
</p>
|
|
<ul class="org-ul">
|
|
<li>The user name of the client which is provided when it joins.
|
|
</li>
|
|
<li>Names and file descriptors of the to-client and to-server FIFOs. The
|
|
file descriptors are opened by the server based on the file names
|
|
the provided by the client and used for communication between them.
|
|
</li>
|
|
<li>A <code>data_ready</code> flag which is set and cleared by the server as
|
|
messages are available.
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-6-2" class="outline-3">
|
|
<h3 id="sec-6-2"><span class="section-number-3">6.2</span> Server Operations: <code>server.c</code></h3>
|
|
<div class="outline-text-3" id="text-6-2">
|
|
<p>
|
|
To facilitate operations of <code>bl-server</code> main program, complete the
|
|
<code>server.c</code> file which provides service routines that mainly manipulate
|
|
<code>server_t</code> structures. Each of these has a purpose to serve in the
|
|
ultimate goal of the server.
|
|
</p>
|
|
|
|
<pre class="example">client_t *server_get_client(server_t *server, int idx);
|
|
// Gets a pointer to the client_t struct at the given index. If the
|
|
// index is beyond n_clients, the behavior of the function is
|
|
// unspecified and may cause a program crash.
|
|
|
|
void server_start(server_t *server, char *server_name, int perms);
|
|
// Initializes and starts the server with the given name. A join fifo
|
|
// called "server_name.fifo" should be created. Removes any existing
|
|
// file of that name prior to creation. Opens the FIFO and stores its
|
|
// file descriptor in join_fd._
|
|
//
|
|
// ADVANCED: create the log file "server_name.log" and write the
|
|
// initial empty who_t contents to its beginning. Ensure that the
|
|
// log_fd is position for appending to the end of the file. Create the
|
|
// POSIX semaphore "/server_name.sem" and initialize it to 1 to
|
|
// control access to the who_t portion of the log.
|
|
|
|
void server_shutdown(server_t *server);
|
|
// Shut down the server. Close the join FIFO and unlink (remove) it so
|
|
// that no further clients can join. Send a BL_SHUTDOWN message to all
|
|
// clients and proceed to remove all clients in any order.
|
|
//
|
|
// ADVANCED: Close the log file. Close the log semaphore and unlink
|
|
// it.
|
|
|
|
int server_add_client(server_t *server, join_t *join);
|
|
// Adds a client to the server according to the parameter join which
|
|
// should have fileds such as name filed in. The client data is
|
|
// copied into the client[] array and file descriptors are opened for
|
|
// its to-server and to-client FIFOs. Initializes the data_ready field
|
|
// for the client to 0. Returns 0 on success and non-zero if the
|
|
// server as no space for clients (n_clients == MAXCLIENTS).
|
|
|
|
int server_remove_client(server_t *server, int idx);
|
|
// Remove the given client likely due to its having departed or
|
|
// disconnected. Close fifos associated with the client and remove
|
|
// them. Shift the remaining clients to lower indices of the client[]
|
|
// array and decrease n_clients.
|
|
|
|
int server_broadcast(server_t *server, mesg_t *mesg);
|
|
// Send the given message to all clients connected to the server by
|
|
// writing it to the file descriptors associated with them.
|
|
//
|
|
// ADVANCED: Log the broadcast message unless it is a PING which
|
|
// should not be written to the log.
|
|
|
|
void server_check_sources(server_t *server);
|
|
// Checks all sources of data for the server to determine if any are
|
|
// ready for reading. Sets the servers join_ready flag and the
|
|
// data_ready flags of each of client if data is ready for them.
|
|
// Makes use of the select() system call to efficiently determine
|
|
// which sources are ready.
|
|
|
|
int server_join_ready(server_t *server);
|
|
// Return the join_ready flag from the server which indicates whether
|
|
// a call to server_handle_join() is safe.
|
|
|
|
int server_handle_join(server_t *server);
|
|
// Call this function only if server_join_ready() returns true. Read a
|
|
// join request and add the new client to the server. After finishing,
|
|
// set the servers join_ready flag to 0.
|
|
|
|
int server_client_ready(server_t *server, int idx);
|
|
// Return the data_ready field of the given client which indicates
|
|
// whether the client has data ready to be read from it.
|
|
|
|
int server_handle_client(server_t *server, int idx);
|
|
// Process a message from the specified client. This function should
|
|
// only be called if server_client_ready() returns true. Read a
|
|
// message from to_server_fd and analyze the message kind. Departure
|
|
// and Message types should be broadcast to all other clients. Ping
|
|
// responses should only change the last_contact_time below. Behavior
|
|
// for other message types is not specified. Clear the client's
|
|
// data_ready flag so it has value 0.
|
|
//
|
|
// ADVANCED: Update the last_contact_time of the client to the current
|
|
// server time_sec.
|
|
|
|
void server_tick(server_t *server);
|
|
// ADVANCED: Increment the time for the server
|
|
|
|
void server_ping_clients(server_t *server);
|
|
// ADVANCED: Ping all clients in the server by broadcasting a ping.
|
|
|
|
void server_remove_disconnected(server_t *server, int disconnect_secs);
|
|
// ADVANCED: Check all clients to see if they have contacted the
|
|
// server recently. Any client with a last_contact_time field equal to
|
|
// or greater than the parameter disconnect_secs should be
|
|
// removed. Broadcast that the client was disconnected to remaining
|
|
// clients. Process clients from lowest to highest and take care of
|
|
// loop indexing as clients may be removed during the loop
|
|
// necessitating index adjustments.
|
|
|
|
void server_write_who(server_t *server);
|
|
// ADVANCED: Write the current set of clients logged into the server
|
|
// to the BEGINNING the log_fd. Ensure that the write is protected by
|
|
// locking the semaphore associated with the log file. Since it may
|
|
// take some time to complete this operation (acquire semaphore then
|
|
// write) it should likely be done in its own thread to preven the
|
|
// main server operations from stalling. For threaded I/O, consider
|
|
// using the pwrite() function to write to a specific location in an
|
|
// open file descriptor which will not alter the position of log_fd so
|
|
// that appends continue to write to the end of the file.
|
|
|
|
void server_log_message(server_t *server, mesg_t *mesg);
|
|
// ADVANCED: Write the given message to the end of log file associated
|
|
// with the server.
|
|
</pre>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-6-3" class="outline-3">
|
|
<h3 id="sec-6-3"><span class="section-number-3">6.3</span> Messages Handled by the Server</h3>
|
|
<div class="outline-text-3" id="text-6-3">
|
|
<p>
|
|
The function <code>server_handle_client()</code> is a workhorse that will read a
|
|
message from a client and respond take appropriate action. Here are
|
|
the messages that the server should accept and respond to.
|
|
</p>
|
|
|
|
<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
|
|
|
|
|
|
<colgroup>
|
|
<col class="left">
|
|
|
|
<col class="left">
|
|
|
|
<col class="left">
|
|
|
|
<col class="left">
|
|
</colgroup>
|
|
<thead>
|
|
<tr>
|
|
<th scope="col" class="left">kind</th>
|
|
<th scope="col" class="left">Name</th>
|
|
<th scope="col" class="left">Body?</th>
|
|
<th scope="col" class="left">Action</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td class="left"><code>BL_MESG</code></td>
|
|
<td class="left">Yes</td>
|
|
<td class="left">Yes</td>
|
|
<td class="left">Broadcast message to all clients.</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="left"><code>BL_DEPARTED</code></td>
|
|
<td class="left">Yes</td>
|
|
<td class="left">No</td>
|
|
<td class="left">Broadcast message to all clients.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-6-4" class="outline-3">
|
|
<h3 id="sec-6-4"><span class="section-number-3">6.4</span> Other Messages Sent by the Server</h3>
|
|
<div class="outline-text-3" id="text-6-4">
|
|
<p>
|
|
The server will broadcast several other kinds of messages to clients
|
|
under the following circumstances.
|
|
</p>
|
|
<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
|
|
|
|
|
|
<colgroup>
|
|
<col class="left">
|
|
|
|
<col class="left">
|
|
|
|
<col class="left">
|
|
|
|
<col class="left">
|
|
</colgroup>
|
|
<thead>
|
|
<tr>
|
|
<th scope="col" class="left">kind</th>
|
|
<th scope="col" class="left">Name</th>
|
|
<th scope="col" class="left">Body?</th>
|
|
<th scope="col" class="left">Circumstance</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td class="left"><code>BL_JOINED</code></td>
|
|
<td class="left">Yes</td>
|
|
<td class="left">No</td>
|
|
<td class="left">Broadcast when a new client joins the server</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="left"><code>BL_SHUTDOWN</code></td>
|
|
<td class="left">No</td>
|
|
<td class="left">No</td>
|
|
<td class="left">Broadcast when the server starts shutting down</td>
|
|
</tr>
|
|
</tbody>
|
|
<tbody>
|
|
<tr>
|
|
<td class="left">ADVANCED</td>
|
|
<td class="left"> </td>
|
|
<td class="left"> </td>
|
|
<td class="left"> </td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="left"><code>BL_PING</code></td>
|
|
<td class="left">No</td>
|
|
<td class="left">No</td>
|
|
<td class="left">Broadcast periodically, clients should respond with a ping to indicate liveness</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="left"><code>BL_DISCONNECTED</code></td>
|
|
<td class="left">Yes</td>
|
|
<td class="left">No</td>
|
|
<td class="left">Broadcast when a client has not pinged in a while to indicate disconnection.</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<div id="outline-container-sec-6-5" class="outline-3">
|
|
<h3 id="sec-6-5"><span class="section-number-3">6.5</span> <code>bl-server.c</code> main function</h3>
|
|
<div class="outline-text-3" id="text-6-5">
|
|
<p>
|
|
Define a <code>main()</code> entry point in <code>bl-server</code> that ties all of the
|
|
server operations together into a function unit.
|
|
</p>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-6-5-1" class="outline-4">
|
|
<h4 id="sec-6-5-1">Listen, Select, Respond</h4>
|
|
<div class="outline-text-4" id="text-6-5-1">
|
|
<p>
|
|
The server <code>main()</code> function in its simplest form boils down to the
|
|
following pseudocode.
|
|
</p>
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-text">REPEAT:
|
|
check all sources
|
|
handle a join request if on is ready
|
|
for each client{
|
|
if the client is ready handle data from it
|
|
}
|
|
}
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
The advanced features build somewhat on this but not by much.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-6-5-2" class="outline-4">
|
|
<h4 id="sec-6-5-2">Signal Handling</h4>
|
|
<div class="outline-text-4" id="text-6-5-2">
|
|
<p>
|
|
The server should run indefinitely without interaction from an
|
|
interactive user. To stop it, send signals. The server should handle
|
|
<code>SIGTERM</code> and <code>SIGINT</code> by shutting down gracefully: exit the main
|
|
computation, call <code>server_shutdown()</code> and return 0.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
|
|
<div id="outline-container-sec-7" class="outline-2">
|
|
<h2 id="sec-7"><span class="section-number-2">7</span> The Client</h2>
|
|
<div class="outline-text-2" id="text-7">
|
|
<p>
|
|
While <code>bl-server</code> is a perpetual, non-interactive program, it is not
|
|
interesting with clients to connect to it allowing users to
|
|
communicate. <code>bl-client</code> is such a program. It allows a user to type
|
|
into the terminal to send text to the server and receive text back
|
|
from the server which is printed to the screen. The sections below
|
|
describe how to build it.
|
|
</p>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-7-1" class="outline-3">
|
|
<h3 id="sec-7-1"><span class="section-number-3">7.1</span> Simplified Terminal I/O</h3>
|
|
<div class="outline-text-3" id="text-7-1">
|
|
<p>
|
|
Standard terminal input and output work well in many situations but
|
|
the <code>bl-client</code> must intermingle the user typing while data may be
|
|
printed to the screen. This calls for somewhat finer control. To
|
|
simplify the murky area that is terminal control, the file <code>simpio.c</code>
|
|
provides functions which have the following net effect.
|
|
</p>
|
|
<ul class="org-ul">
|
|
<li>A prompt can be set that is always displayed as the last final
|
|
advancing line in the terminal.
|
|
</li>
|
|
<li>Text can be typed and deleted by the user.
|
|
</li>
|
|
<li>Any thread printing with the <code>iprintf()</code> function will advance the
|
|
prompt forwards without disrupting the text a user may be typing.
|
|
</li>
|
|
</ul>
|
|
|
|
<p>
|
|
The program <code>simpio-demo.c</code> demonstrates this facility by spinning up
|
|
a user and background thread which both print to the screen. Text
|
|
printed by the background thread using <code>iprintf()</code> does not disrupt
|
|
text being typed by the user at the prompt.
|
|
</p>
|
|
|
|
<p>
|
|
Use <code>simpio-demo.c</code> as a template to begin you development on
|
|
<code>bl-client.c</code> noting the following.
|
|
</p>
|
|
<ul class="org-ul">
|
|
<li>Initialize the simplified terminal I/O with the following sequence
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-c">simpio_set_prompt(simpio, prompt); // set the prompt
|
|
simpio_reset(simpio); // initialize io
|
|
simpio_noncanonical_terminal_mode(); // set the terminal into a compatible mode
|
|
</pre>
|
|
</div>
|
|
</li>
|
|
<li>When threads want to print, use the <code>iprintf()</code> function. It works
|
|
like <code>printf()</code> but takes as its first argument a <code>simpio_t</code> object
|
|
which manages the prompt and typed text.
|
|
</li>
|
|
<li>Analyze the input loop in <code>simpio-demo.c</code> to see how to read
|
|
characters from the prompt, detect a completed line, and end of
|
|
input.
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-7-2" class="outline-3">
|
|
<h3 id="sec-7-2"><span class="section-number-3">7.2</span> <code>bl-client.c</code> Features</h3>
|
|
<div class="outline-text-3" id="text-7-2">
|
|
<p>
|
|
Unlike the server, there are no required C functions for the
|
|
client. Instead, there are a series of required features and
|
|
suggestions on how to implement them.
|
|
</p>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-7-2-1" class="outline-4">
|
|
<h4 id="sec-7-2-1">Client Name and FIFO Creation</h4>
|
|
<div class="outline-text-4" id="text-7-2-1">
|
|
<p>
|
|
The client program is run as follows
|
|
</p>
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-sh">$> bl-client server1 Lois
|
|
# join the server1 as a user Lois
|
|
|
|
$> bl-client dc-serv Bruce
|
|
# join the dc-serv server as user Bruce
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
The first argument is the server to join and corresponds to a FIFO
|
|
name that is owned by the server.
|
|
</p>
|
|
|
|
<p>
|
|
The client should create its own to-client and to-server FIFOs which
|
|
become part of the join request to the server. The names of these
|
|
FIFOs can be selected arbitrarily so long as they do not conflict with
|
|
other user FIFO names. Examples are to create temporary file names or
|
|
use the PID of the client process to choose the FIFO names.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-7-2-2" class="outline-4">
|
|
<h4 id="sec-7-2-2">Joining the Server</h4>
|
|
<div class="outline-text-4" id="text-7-2-2">
|
|
<p>
|
|
The client should construct a <code>join_t</code> with its name and the names of
|
|
its to-client and to-server FIFOs. This should be written to the name
|
|
of the server's FIFO which will notify the server and other clients of
|
|
the new user's arrival.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-7-2-3" class="outline-4">
|
|
<h4 id="sec-7-2-3">Messages Handled by Client</h4>
|
|
<div class="outline-text-4" id="text-7-2-3">
|
|
<p>
|
|
The client should handle the following kinds of messages from the server.
|
|
</p>
|
|
<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
|
|
|
|
|
|
<colgroup>
|
|
<col class="left">
|
|
|
|
<col class="left">
|
|
|
|
<col class="left">
|
|
|
|
<col class="left">
|
|
|
|
<col class="left">
|
|
</colgroup>
|
|
<thead>
|
|
<tr>
|
|
<th scope="col" class="left">kind</th>
|
|
<th scope="col" class="left">Name</th>
|
|
<th scope="col" class="left">Body?</th>
|
|
<th scope="col" class="left">Action</th>
|
|
<th scope="col" class="left">Print Format / Example</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td class="left"><code>BL_MESG</code></td>
|
|
<td class="left">Yes</td>
|
|
<td class="left">Yes</td>
|
|
<td class="left">Print</td>
|
|
<td class="left"><code>[Bruce] : check this out</code></td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="left"><code>BL_JOINED</code></td>
|
|
<td class="left">Yes</td>
|
|
<td class="left">No</td>
|
|
<td class="left">Print</td>
|
|
<td class="left"><code>-- Bruce JOINED --</code></td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="left"><code>BL_DEPARTED</code></td>
|
|
<td class="left">Yes</td>
|
|
<td class="left">No</td>
|
|
<td class="left">Print</td>
|
|
<td class="left"><code>-- Clark DEPARTED --</code></td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="left"><code>BL_SHUTDOWN</code></td>
|
|
<td class="left">No</td>
|
|
<td class="left">No</td>
|
|
<td class="left">Print</td>
|
|
<td class="left"><code>!!! server is shutting down !!!</code></td>
|
|
</tr>
|
|
</tbody>
|
|
<tbody>
|
|
<tr>
|
|
<td class="left">ADVANCED</td>
|
|
<td class="left"> </td>
|
|
<td class="left"> </td>
|
|
<td class="left"> </td>
|
|
<td class="left"> </td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="left"><code>BL_DISCONNECTED</code></td>
|
|
<td class="left">Yes</td>
|
|
<td class="left">No</td>
|
|
<td class="left">Print</td>
|
|
<td class="left"><code>-- Clark DISCONNECTED --</code></td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="left"><code>BL_PING</code></td>
|
|
<td class="left">No</td>
|
|
<td class="left">No</td>
|
|
<td class="left">Reply</td>
|
|
<td class="left">Send <code>BL_PING</code> message back to server</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-7-2-4" class="outline-4">
|
|
<h4 id="sec-7-2-4">User Input and Messages from the Server</h4>
|
|
<div class="outline-text-4" id="text-7-2-4">
|
|
<p>
|
|
To make the user experience reasonable, server messages should be
|
|
received and printed to the screen as soon as they are available.
|
|
Printing server messages should not disrupt the text input too
|
|
much. This combination of requirements suggests the following.
|
|
</p>
|
|
<ul class="org-ul">
|
|
<li><b>Use two threads</b>, one for user interactions and the other for
|
|
server interactions.
|
|
</li>
|
|
<li>The user thread performs an input loop until the user has completed
|
|
a line. It then writes message data into the to-server FIFO to get
|
|
it to the server and goes back to reading user input.
|
|
</li>
|
|
<li>The server thread reads data from the to-client FIFO and prints to
|
|
the screen as data is read.
|
|
</li>
|
|
<li>Both user and server threads use the <code>iprintf()</code> function to ensure
|
|
that data appears correctly on the screen and cooperates with input
|
|
being typed.
|
|
</li>
|
|
</ul>
|
|
|
|
<p>
|
|
A few additional notes are in order on the interaction of these two
|
|
threads.
|
|
</p>
|
|
<ul class="org-ul">
|
|
<li>Should the user thread receive and end of input, it should send a
|
|
message to the server with kind <code>BL_DEPARTED</code> to indicate the client
|
|
is shutting down. This will notify other users of the departure. The
|
|
user thread should cancel the server thread and return.
|
|
</li>
|
|
<li>If the server thread receives a <code>BL_SHUTDOWN</code> message, the server is
|
|
shutting down. This means the client should exit as well. The server
|
|
thread should cancel the user thread and return.
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-7-2-5" class="outline-4">
|
|
<h4 id="sec-7-2-5">Typed Input is Sent to the Server, not Printed</h4>
|
|
<div class="outline-text-4" id="text-7-2-5">
|
|
<p>
|
|
When users type input, it is echoed onto the screen by <code>simpio</code> at the
|
|
prompt. However, on hitting enter, the data is sent immediately to the
|
|
server as a <code>mesg_t</code> with kind <code>MESG</code>, <code>name</code> filled in with the
|
|
user's name and <code>body</code> filled in with the text line typed.
|
|
</p>
|
|
|
|
<p>
|
|
Though the message body is known by the client which just sent it, the
|
|
body is not printed to the screen. Instead, the client waits for the
|
|
server to broadcast the message back and prints its own message just
|
|
as if it were a message from another user. This ensures that no
|
|
special actions need to be taken to avoid duplicate messages.
|
|
</p>
|
|
|
|
<p>
|
|
This "print only what the server sends" feature restriction is
|
|
somewhat modified by some of the advanced features described later.
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-7-3" class="outline-3">
|
|
<h3 id="sec-7-3"><span class="section-number-3">7.3</span> Client Main Approach</h3>
|
|
<div class="outline-text-3" id="text-7-3">
|
|
<p>
|
|
To summarize, <code>bl-client</code> will roughly take the following steps.
|
|
</p>
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-text">read name of server and name of user from command line args
|
|
create to-server and to-client FIFOs
|
|
write a join_t request to the server FIFO
|
|
start a user thread to read inpu
|
|
start a server thread to listen to the server
|
|
wait for threads to return
|
|
restore standard terminal output
|
|
|
|
user thread{
|
|
repeat:
|
|
read input using simpio
|
|
when a line is ready
|
|
create a mesg_t with the line and write it to the to-server FIFO
|
|
until end of input
|
|
write a DEPARTED mesg_t into to-server
|
|
cancel the server thread
|
|
|
|
server thread{
|
|
repeat:
|
|
read a mesg_t from to-client FIFO
|
|
print appropriate response to terminal with simpio
|
|
until a SHUTDOWN mesg_t is read
|
|
cancel the user thread
|
|
</pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-8" class="outline-2">
|
|
<h2 id="sec-8"><span class="section-number-2">8</span> Manual Inspection Criteria (50%)</h2>
|
|
<div class="outline-text-2" id="text-8">
|
|
<p>
|
|
The following criteria will be examined during manual inspection of
|
|
code by graders. Use this as a guide to avoid omitting important steps
|
|
or committing bad style fouls.
|
|
</p>
|
|
|
|
<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
|
|
|
|
|
|
<colgroup>
|
|
<col class="left">
|
|
|
|
<col class="right">
|
|
|
|
<col class="left">
|
|
</colgroup>
|
|
<thead>
|
|
<tr>
|
|
<th scope="col" class="left">Location</th>
|
|
<th scope="col" class="right">Wgt</th>
|
|
<th scope="col" class="left">Criteria</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td class="left"><b>Makefile</b></td>
|
|
<td class="right">5</td>
|
|
<td class="left">A Makefile is provided which compiles commando</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="left"> </td>
|
|
<td class="right"> </td>
|
|
<td class="left">Any required test targets are present.</td>
|
|
</tr>
|
|
</tbody>
|
|
<tbody>
|
|
<tr>
|
|
<td class="left"><b>server.c</b></td>
|
|
<td class="right"> </td>
|
|
<td class="left"> </td>
|
|
</tr>
|
|
</tbody>
|
|
<tbody>
|
|
<tr>
|
|
<td class="left"><code>server_start()</code></td>
|
|
<td class="right">5</td>
|
|
<td class="left">creates and opens FIFO correctly for joins, removes existing FIFO</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="left"><code>server_shutdown()</code></td>
|
|
<td class="right"> </td>
|
|
<td class="left">closes and removes FIFO to prevent additional joins</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="left"> </td>
|
|
<td class="right"> </td>
|
|
<td class="left">broadcasts a shutdown message</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="left"> </td>
|
|
<td class="right"> </td>
|
|
<td class="left">does basic error checking of system calls</td>
|
|
</tr>
|
|
</tbody>
|
|
<tbody>
|
|
<tr>
|
|
<td class="left"><code>server_add_client()</code></td>
|
|
<td class="right">5</td>
|
|
<td class="left">does bounds checking to prevent overflow on add</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="left"> </td>
|
|
<td class="right"> </td>
|
|
<td class="left">adds client to end of array and increments <code>n_clients</code></td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="left"> </td>
|
|
<td class="right"> </td>
|
|
<td class="left">fills in fixed fields of client data based on join parameter</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="left"> </td>
|
|
<td class="right"> </td>
|
|
<td class="left">makes use of strncpy() to prevent buffer overruns</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="left"> </td>
|
|
<td class="right"> </td>
|
|
<td class="left">opens to-client and to-server FIFOs for reading</td>
|
|
</tr>
|
|
</tbody>
|
|
<tbody>
|
|
<tr>
|
|
<td class="left"><code>server_remove_client()</code></td>
|
|
<td class="right">5</td>
|
|
<td class="left">uses <code>server_get_client()</code> for readability</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="left"> </td>
|
|
<td class="right"> </td>
|
|
<td class="left">closes to-client and from-client FIFOs</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="left"> </td>
|
|
<td class="right"> </td>
|
|
<td class="left">correctly shifts array of clients to maintain contiguous client array</td>
|
|
</tr>
|
|
</tbody>
|
|
<tbody>
|
|
<tr>
|
|
<td class="left"><code>server_check_sources()</code></td>
|
|
<td class="right">5</td>
|
|
<td class="left">makes use of <code>select()</code> system call to detect ready clients/joins</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="left"> </td>
|
|
<td class="right"> </td>
|
|
<td class="left">checks join FIFO and all clients in <code>select()</code> call</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="left"> </td>
|
|
<td class="right"> </td>
|
|
<td class="left">does not read data but sets <code>read</code> flags for join and clients</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="left"> </td>
|
|
<td class="right"> </td>
|
|
<td class="left">does basic error checking of system calls</td>
|
|
</tr>
|
|
</tbody>
|
|
<tbody>
|
|
<tr>
|
|
<td class="left"><code>server_handle_join()</code></td>
|
|
<td class="right">5</td>
|
|
<td class="left">reads a <code>join_t</code> from join FIFO correctly</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="left"> </td>
|
|
<td class="right"> </td>
|
|
<td class="left">adds client with <code>server_add_client()</code></td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="left"> </td>
|
|
<td class="right"> </td>
|
|
<td class="left">broadcasts join</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="left"><code>server_handle_client()</code></td>
|
|
<td class="right"> </td>
|
|
<td class="left">reads a <code>mesg_t</code> from the to-server FIFO</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="left"> </td>
|
|
<td class="right"> </td>
|
|
<td class="left">processes message properly and broadcasts if needed</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="left"> </td>
|
|
<td class="right"> </td>
|
|
<td class="left">does basic error checking of system calls</td>
|
|
</tr>
|
|
</tbody>
|
|
<tbody>
|
|
<tr>
|
|
<td class="left"><b>bl-server.c</b></td>
|
|
<td class="right"> </td>
|
|
<td class="left"> </td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="left"> </td>
|
|
<td class="right">5</td>
|
|
<td class="left">main loop makes use of the <code>server.c</code> routines extensively</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="left"> </td>
|
|
<td class="right"> </td>
|
|
<td class="left">clear code to check input sources and handle ready input</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="left"> </td>
|
|
<td class="right"> </td>
|
|
<td class="left">signal handling for graceful shutdown is clear</td>
|
|
</tr>
|
|
</tbody>
|
|
<tbody>
|
|
<tr>
|
|
<td class="left"><b>bl-client.c</b></td>
|
|
<td class="right"> </td>
|
|
<td class="left"> </td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="left">main and overall</td>
|
|
<td class="right">5</td>
|
|
<td class="left">proper setup of terminal with simpio</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="left"> </td>
|
|
<td class="right"> </td>
|
|
<td class="left">use of simpio for input and output</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="left"> </td>
|
|
<td class="right"> </td>
|
|
<td class="left">clear creation and joining of threads</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="left"> </td>
|
|
<td class="right"> </td>
|
|
<td class="left">resets terminal at end of run</td>
|
|
</tr>
|
|
</tbody>
|
|
<tbody>
|
|
<tr>
|
|
<td class="left">user thread</td>
|
|
<td class="right">5</td>
|
|
<td class="left">clear use of a user thread to handle typed input</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="left"> </td>
|
|
<td class="right"> </td>
|
|
<td class="left">user thread sends data to server</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="left"> </td>
|
|
<td class="right"> </td>
|
|
<td class="left">cancels server thread at end of input before returning</td>
|
|
</tr>
|
|
</tbody>
|
|
<tbody>
|
|
<tr>
|
|
<td class="left">server thread</td>
|
|
<td class="right">5</td>
|
|
<td class="left">clear use of a server thread to listen data on to-client FIFO</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="left"> </td>
|
|
<td class="right"> </td>
|
|
<td class="left">clear handling of different kinds of messages coming from server</td>
|
|
</tr>
|
|
|
|
<tr>
|
|
<td class="left"> </td>
|
|
<td class="right"> </td>
|
|
<td class="left">cancels user thread on receiving shutdown message and returns</td>
|
|
</tr>
|
|
</tbody>
|
|
<tbody>
|
|
<tr>
|
|
<td class="left"> </td>
|
|
<td class="right">50</td>
|
|
<td class="left">Total</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<div id="outline-container-sec-9" class="outline-2">
|
|
<h2 id="sec-9"><span class="section-number-2">9</span> ADVANCED Features</h2>
|
|
<div class="outline-text-2" id="text-9">
|
|
<p>
|
|
The following advanced features may be implemented to garner extra
|
|
credit on the total project score for the semester. Each additional
|
|
feature is worth the extra credit indicated.
|
|
</p>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-9-1" class="outline-3">
|
|
<h3 id="sec-9-1"><span class="section-number-3">9.1</span> Server Ping and Disconnected Clients (10%)</h3>
|
|
<div class="outline-text-3" id="text-9-1">
|
|
<p>
|
|
Clients may terminate abruptly in the real world before they have a
|
|
chance to send a <code>BL_DEPARTED</code> message to the server. This additional
|
|
feature adds period <b>pinging</b> to the server and clients. A ping is a
|
|
short message just to establish whether a communication partner is
|
|
still present. In this case, it is a message with kind <code>BL_PING</code>.
|
|
</p>
|
|
|
|
<p>
|
|
Implementing this feature will cause the server broadcast a ping to
|
|
all clients every second. Clients should respond immediately by
|
|
sending a ping back.
|
|
</p>
|
|
|
|
<p>
|
|
To detect disconnected clients, the server should maintain its
|
|
<code>time_sec</code> incrementing it each second. Whenever a message is
|
|
received from a client, including <code>BL_PING</code> messages, the server
|
|
updates the client's <code>last_contact_time</code> to the current server
|
|
time. Any client that abruptly departs will eventually have a large
|
|
gap between its <code>last_contact_time</code> and the <code>time_sec</code>.
|
|
</p>
|
|
|
|
<p>
|
|
Every second, the server runs the function
|
|
<code>server_remove_disconnected(server, disconnect_secs)</code>. If any client
|
|
with a difference in <code>last_contact_time</code> and
|
|
<code>server_remove_disconnected</code> that is larger than the argument
|
|
<code>disconnect_secs</code> should be removed. A <code>BL_DISCONNECTED</code> message
|
|
should be broadcast for this client to notify other clients of the
|
|
change.
|
|
</p>
|
|
|
|
<p>
|
|
<b>A good way to implement periodic activity</b> is to use the <code>alarm()</code>
|
|
function. This arranges for a periodic signal to be sent to the server
|
|
process. This should be done in <code>main()</code> for <code>bl-server.c</code>. The
|
|
signal handler for the <code>SIGALRM</code> that is raised can set a variable to
|
|
indicate that 1 second has passed. In the main loop of the server, a
|
|
condition checks this variable and performs the ping broadcast and
|
|
checks for disconnected clients.
|
|
</p>
|
|
|
|
<p>
|
|
All changes for this feature are on the server side. Additional
|
|
functions to write or modify are as follows.
|
|
</p>
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-c">// server.c
|
|
// Modify
|
|
int server_handle_client(server_t *server, int idx)
|
|
|
|
// Write
|
|
void server_tick(server_t *server)
|
|
void server_ping_clients(server_t *server)
|
|
void server_remove_disconnected(server_t *server, int disconnect_secs)
|
|
|
|
// bl-server.c
|
|
int main(int argc, char *argv[])
|
|
</pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-9-2" class="outline-3">
|
|
<h3 id="sec-9-2"><span class="section-number-3">9.2</span> Binary Server Log File (10%)</h3>
|
|
<div class="outline-text-3" id="text-9-2">
|
|
<p>
|
|
There is cause to want a log of all messages that pass through a
|
|
server. This feature will cause the server to write such a log in a
|
|
binary file.
|
|
</p>
|
|
|
|
<p>
|
|
The file should be named after the server name similarly to the join
|
|
FIFO. For example
|
|
</p>
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-sh">$> bl-server server1
|
|
# creates server1.fifo
|
|
# creates server1.log
|
|
|
|
$> bl-server batcave
|
|
# creates batcave.fifo
|
|
# creates batcave.log
|
|
</pre>
|
|
</div>
|
|
|
|
|
|
<p>
|
|
The format of this binary log file is as follows.
|
|
</p>
|
|
<ul class="org-ul">
|
|
<li>The first part should contain a binary <code>who_t</code> structure which has
|
|
the active users in it. To complete the logging feature, the
|
|
<code>who_t</code> does not need to be kept to date.
|
|
</li>
|
|
<li>After the <code>who_t</code> is a growing sequence of <code>mesg_t</code> structs in the
|
|
log file. Any message that is broadcast by the server EXCEPT for
|
|
pings is written to the end of this log, NOT in text format but as
|
|
the direct binary representation of a <code>mesg_t</code>.
|
|
</li>
|
|
<li>Each new message that is broadcast is appended to the end of the log
|
|
in binary format.
|
|
</li>
|
|
</ul>
|
|
|
|
<p>
|
|
When the server starts up, the log file should be created and the
|
|
<code>log_fd</code> field filled with its file descriptor. A good place to write
|
|
log messages is during <code>server_broadcast()</code>. In it, any message that
|
|
is not a ping should be written to the end of log.
|
|
</p>
|
|
|
|
<p>
|
|
When the server shuts down, close the file descriptor of the log but
|
|
do not remove the file. On startup, re-open any existing log and
|
|
continue appending to it.
|
|
</p>
|
|
|
|
<p>
|
|
This feature is implemented entirely in the server and requires
|
|
modification of the following functions.
|
|
</p>
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-c">// server.c
|
|
void server_start(server_t *server, char *server_name, int perms)
|
|
void server_shutdown(server_t *server)
|
|
int server_broadcast(server_t *server, mesg_t *mesg)
|
|
void server_write_who(server_t *server)
|
|
void server_log_message(server_t *server, mesg_t *mesg)
|
|
|
|
// bl-server.c
|
|
int main(int argc, char *argv[])
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
In addition, provide a file called <code>bl-showlog.c</code> which will read the
|
|
binary log file and print its output. This should include the <code>who_t</code>
|
|
at the beginning and all log messages. Here is a demo run including
|
|
the presumed <code>Makefile</code> target. Output is nearly identical to what is
|
|
shown in the client.
|
|
</p>
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-text">> make bl-showlog
|
|
gcc -Wall -g -c bl-showlog.c
|
|
gcc -Wall -g -c util.c
|
|
gcc -Wall -g -o bl-showlog bl-showlog.o util.o -lpthread
|
|
|
|
> file server1.log
|
|
server1.log: data
|
|
|
|
> ./bl-showlog server1.log
|
|
3 CLIENTS
|
|
0: Batman
|
|
1: Clark
|
|
2: Barbara
|
|
MESSAGES
|
|
-- Bruce JOINED --
|
|
-- Clark JOINED --
|
|
-- Lois JOINED --
|
|
[Bruce] : hey, want to know secret identity?
|
|
[Clark] : dude, I have x-ray vision
|
|
[Lois] : wait, you have x-ray vision
|
|
[Clark] : ah, er, I mean...
|
|
[Bruce] : ha ha. I'd never do something dumb like that.
|
|
[Lois] : why not?
|
|
[Clark] : oh boy, here it comes...
|
|
[Bruce] : because...
|
|
[Lois] : ??
|
|
[Bruce] : AHYM BAAATMAN!!!
|
|
[Clark] : walked into that one
|
|
[Lois] : yup
|
|
-- Barbara JOINED --
|
|
[Barbara] : hey guys
|
|
[Clark] : hey Barbara
|
|
[Lois] : what up!
|
|
[Barbara] : Did I miss anything important?
|
|
[Clark] : the big "reveal" from Bruce...
|
|
[Barbara] : what, that he's Batman?
|
|
[Lois] : yup
|
|
[Bruce] : wait, how did you know that?
|
|
[Barbara] : you told me when we were dating
|
|
[Lois] : me too
|
|
[Bruce] : awkward. time for a SMOKE BOMB!!!
|
|
-- Bruce DEPARTED --
|
|
[Barbara] : that guy
|
|
>
|
|
</pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-9-3" class="outline-3">
|
|
<h3 id="sec-9-3"><span class="section-number-3">9.3</span> Last Messages for Client (10%)</h3>
|
|
<div class="outline-text-3" id="text-9-3">
|
|
<p>
|
|
This feature requires the Binary Server Log File Feature.
|
|
</p>
|
|
|
|
<p>
|
|
Clients that recently join a server have no idea what has transpired
|
|
prior to their joining. This can be ameliorated if clients can access
|
|
the binary log to examine the last N messages. For example:
|
|
</p>
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-text">$> bl-client server1 Lois
|
|
-- Lois JOINED --
|
|
[Clark] : eek!
|
|
-- Clark DEPARTED --
|
|
[Lois] : what's his deal?
|
|
[Bruce] : um..
|
|
|
|
Lois> %last 10
|
|
====================
|
|
LAST 10 MESSAGES
|
|
[Bruce] : what up man?
|
|
[Clark] : not much, just down in the fortress of solitude
|
|
[Bruce] : with lois
|
|
[Clark] : nope. lana
|
|
[Bruce] : nice
|
|
-- Lois JOINED --
|
|
[Clark] : eek!
|
|
-- Clark DEPARTED --
|
|
[Lois] : what's his deal?
|
|
[Bruce] : um..
|
|
====================
|
|
Lois>> wtf?!?
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
To accomplish this <code>bl-client</code> should examine the typed line that is
|
|
entered to see if it starts with the string <code>%last</code> in which case it
|
|
will be followed by an integer which is the number of messages
|
|
requested.
|
|
</p>
|
|
|
|
<p>
|
|
On detecting this command request, client should open the binary log
|
|
file for the server and seek to the end of it using <code>lseek()</code>. Note
|
|
that the exact position in the binary log file can be calculated
|
|
immediately by using.
|
|
</p>
|
|
<ul class="org-ul">
|
|
<li><code>sizeof(mesg_t</code>
|
|
</li>
|
|
<li>The number of messages requested
|
|
</li>
|
|
<li>The argument <code>SEEK_END</code> to <code>lseek()</code>
|
|
</li>
|
|
</ul>
|
|
<p>
|
|
Thus no looping is required to find that position.
|
|
</p>
|
|
|
|
<p>
|
|
The client should then read off these messages and print them to the
|
|
screen. It is a good idea to write function that will print logged
|
|
messages to keep the main loop and thread loops simple in the client.
|
|
</p>
|
|
|
|
<p>
|
|
<b>No server interaction</b> is required for this feature so long as the
|
|
server is producing the binary log file. Modify only <code>bl-client.c</code>.
|
|
</p>
|
|
|
|
<p>
|
|
Modify the following code for this feature.
|
|
</p>
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-c">// bl-client.c
|
|
// helper functions and maybe main()
|
|
int main(int argc, char *argv[])
|
|
</pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-9-4" class="outline-3">
|
|
<h3 id="sec-9-4"><span class="section-number-3">9.4</span> <code>who_t</code> for Client and Server (10%)</h3>
|
|
<div class="outline-text-3" id="text-9-4">
|
|
<p>
|
|
Users who log into the server have no way of knowing who is logged
|
|
in. This feature ameliorates that.
|
|
</p>
|
|
<ul class="org-ul">
|
|
<li>The server writes its active users as a <code>who_t</code> structure to the
|
|
beginning of its binary log every second at the same time as it
|
|
would check for disconnected users.
|
|
</li>
|
|
<li>Clients can read the <code>who_t</code> at the beginning of the log file to
|
|
determine which users are connected to the server. The client the
|
|
provides a <code>%who</code> command which prints active users.
|
|
</li>
|
|
<li>To prevent the server from writing the <code>who_t</code> structure while a
|
|
client is reading or vice versa, the server creates a semaphore
|
|
which must be acquired to access this part of the log.
|
|
</li>
|
|
</ul>
|
|
|
|
<p>
|
|
The <code>who_t</code> structure is a simple, fixed size array of strings.
|
|
</p>
|
|
<pre class="example">// who_t: data to write into server log for current clients (ADVANCED)
|
|
typedef struct {
|
|
int n_clients; // number of clients on server
|
|
char names[MAXCLIENTS][MAXNAME]; // names of clients
|
|
} who_t;
|
|
</pre>
|
|
|
|
<p>
|
|
This fixed size means every time it is written it will overwrite the
|
|
same bytes. The server should write it every second in the same block
|
|
using the same approach as is used to check for disconnected clients
|
|
(<code>alarm(1)</code>). Use of <code>pwrite()</code> is suggested to allow the <code>log_fd</code> to
|
|
stay in position to write to the end of the log file.
|
|
</p>
|
|
|
|
<p>
|
|
The client should implement the <code>%who</code> command by checking the
|
|
<code>simpio->buf</code> for the string. It should then acquire the semaphore,
|
|
read the <code>who_t</code> and print the results the screen similar to the
|
|
following.
|
|
</p>
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-text">-- Barbara JOINED --
|
|
[Barbara] : Bruce?
|
|
[Barbara] : Bruce, are you there?
|
|
[Clark] : Ummm....
|
|
[Barbara] : hang on
|
|
|
|
Barbara>> %who
|
|
====================
|
|
3 CLIENTS
|
|
0: Batman
|
|
1: Clark
|
|
2: Barbara
|
|
====================
|
|
[Barbara] : (sigh) Batman?
|
|
[Batman] : I AM THE NIGHT!
|
|
Barbara>>
|
|
</pre>
|
|
</div>
|
|
|
|
<p>
|
|
The server is responsible for creating the semaphore which controls
|
|
access to the <code>who_t</code> portion of the log. Follow the same naming
|
|
convention as before.
|
|
</p>
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-sh">$> bl-server server1
|
|
# creates server1.fifo FIFO
|
|
# creates server1.log binary log file
|
|
# creates /server1.sem POSIX semaphore
|
|
|
|
$> bl-server batcave
|
|
# creates batcave.fifo FIFO
|
|
# creates batcave.log binary log file
|
|
# creates /batcave.sem POSIX semaphore
|
|
</pre>
|
|
</div>
|
|
<p>
|
|
A few notes on POSIX semaphores.
|
|
</p>
|
|
<ul class="org-ul">
|
|
<li>They are created / accessed with the <code>sem_open()</code> function which
|
|
takes a name which must start with a forward slash, thus the
|
|
<code>/server1.sem</code> convention.
|
|
</li>
|
|
<li>POSIX semaphores are singular, not arrays of semaphores like System
|
|
V semaphores. The have only <code>sem_wait()</code> (decrement) and
|
|
<code>sem_post()</code> (increment) operations. However, these are sufficient
|
|
for the present purpose.
|
|
</li>
|
|
<li>When the server wants to write a <code>who_t</code> into the log, it acquires
|
|
the semaphore with <code>sem_wait()</code>, writes, then releases with
|
|
<code>sem_post()</code>.
|
|
</li>
|
|
<li>Clients follow a similar protocol when reading the <code>who_t</code>.
|
|
</li>
|
|
<li>When shutting down the, server should unlink the semaphore with
|
|
<code>sem_unlink()</code>.
|
|
</li>
|
|
</ul>
|
|
|
|
<p>
|
|
Modify the following code for this feature.
|
|
</p>
|
|
<div class="org-src-container">
|
|
|
|
<pre class="src src-c">// server.c
|
|
void server_start(server_t *server, char *server_name, int perms)
|
|
void server_shutdown(server_t *server)
|
|
void server_write_who(server_t *server)
|
|
|
|
// bl-server.c
|
|
int main(int argc, char *argv[])
|
|
|
|
|
|
// bl-client.c
|
|
// helper functions and maybe main()
|
|
int main(int argc, char *argv[])
|
|
</pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-10" class="outline-2">
|
|
<h2 id="sec-10"><span class="section-number-2">10</span> <a id="testing" name="testing"></a> Automatic Testing (50%) <span class="tag"><span class="grading">grading</span></span></h2>
|
|
<div class="outline-text-2" id="text-10">
|
|
<p>
|
|
<i>Brewing</i>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-11" class="outline-2">
|
|
<h2 id="sec-11"><span class="section-number-2">11</span> Zip and Submit</h2>
|
|
<div class="outline-text-2" id="text-11">
|
|
</div><div id="outline-container-sec-11-1" class="outline-3">
|
|
<h3 id="sec-11-1"><span class="section-number-3">11.1</span> Submit to Canvas</h3>
|
|
<div class="outline-text-3" id="text-11-1">
|
|
<p>
|
|
Once your are confident your code is working, you are ready to
|
|
submit. Ensure your folder has all of the required files. Create a
|
|
zip archive of your lab folder and submit it to blackboard.
|
|
</p>
|
|
|
|
<p>
|
|
On Canvas:
|
|
</p>
|
|
<ul class="org-ul">
|
|
<li>Click on the <i>Assignments</i> section
|
|
</li>
|
|
<li>Click on the appropriate link for this lab
|
|
</li>
|
|
<li>Scroll down to "Attach a File"
|
|
</li>
|
|
<li>Click "Browse My Computer"
|
|
</li>
|
|
<li>Select you Zip file and press OK
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="outline-container-sec-11-2" class="outline-3">
|
|
<h3 id="sec-11-2"><span class="section-number-3">11.2</span> Late Policies</h3>
|
|
<div class="outline-text-3" id="text-11-2">
|
|
<p>
|
|
You may wish to review the policy on late project submission which
|
|
will cost you late tokens to submit late or credit if you run out of
|
|
tokens.
|
|
</p>
|
|
|
|
<p>
|
|
<a href="http://www-users.cs.umn.edu/~kauffman/4061/syllabus.html#late-projects">http://www-users.cs.umn.edu/~kauffman/4061/syllabus.html#late-projects</a>
|
|
</p>
|
|
|
|
<p>
|
|
<b>No projects will be accepted more than 48 hours after the deadline.</b>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="postamble" class="status">
|
|
<hr> <i> Author: Chris Kauffman (<a href="mailto:kauffman@umn.edu">kauffman@umn.edu</a>) <br> Date: 2017-11-29 Wed 17:46 <br> </i>
|
|
</div>
|
|
|
|
|
|
</body><div id="cVim-status-bar" style="top: 0px;"></div><iframe src="./readme_files/cmdline_frame.html" id="cVim-command-frame"></iframe></html> |