首页 > > 详细

CSSE2310/CSSE7231 Assignment 4

 The University of Queensland

School of Information Technology and Electrical Engineering
CSSE2310/CSSE7231 — Semester 2, 2022
Assignment 4 (version 1.0)
Marks: 75 (for CSSE2310), 85 (for CSSE7231)
Weighting: 15%
Due: 6:00pm Friday 28 October, 2022
Introduction 1
The goal of this assignment is to further develop your C programming skills, and to demonstrate your un- 2
derstanding of networking and multithreaded programming. You are to create two programs which together 3
implement a distributed communication architecture known as publish/subscribe. One program – psserver 4
– is a network server which accepts connections from clients (including psclient, which you will implement). 5
Clients connect, and tell the server that they wish to subscribe to notifications on certain topics. Clients can also 6
publish values (strings) on certain topics. The server will relay a message to all subscribers of a particular topic. 7
Communication between the psclient and psserver is over TCP using a newline-terminated text command 8
protocol. Advanced functionality such as connection limiting, signal handling and statistics reporting are also 9
required for full marks. CSSE7231 students shall also implement a simple HTTP interface to psserver. 10
The assignment will also test your ability to code to a particular programming style guide, to write a library 11
to a provided API, and to use a revision control system appropriately. 12
Student Conduct 13
This is an individual assignment. You should feel free to discuss general aspects of C programming and 14
the assignment specification with fellow students, including on the discussion forum. In general, questions like 15
“How should the program behave if h this happensi ?” would be safe, if they are seeking clarification on the 16
specification. 17
You must not actively help (or seek help from) other students or other people with the actual design, structure 18
and/or coding of your assignment solution. It is cheating to look at another student’s assignment code 19
and it is cheating to allow your code to be seen or shared in printed or electronic form by others. 20
All submitted code will be subject to automated checks for plagiarism and collusion. If we detect plagiarism or 21
collusion, formal misconduct actions will be initiated against you, and those you cheated with. That’s right, if 22
you share your code with a friend, even inadvertently, then both of you are in trouble. Do not post your 23
code to a public place such as the course discussion forum or a public code repository, and do not allow others 24
to access your computer – you must keep your code secure. 25
You must follow the following code referencing rules for all code committed to your SVN repository (not 26
just the version that you submit): 27
28
Code Origin Usage/Referencing
Code provided to you in writing this semester by
CSSE2310/7231 teaching staff (e.g. code hosted on Black￾board, posted on the discussion forum, or shown in class).
May be used freely without reference. (You must be able
to point to the source if queried about it.)
Code you have personally written this semester for
CSSE2310/7231 (e.g. code written for A1 reused in A3)
May be used freely without reference. (This assumes
that no reference was required for the original use.)
Code examples found in man pages on moss. May be used provided the source of the code is
referenced in a comment adjacent to that code. (Code
you have taken inspiration from must not be directly
copied or just converted from one programming
language to another.)
Code you have personally written in a previous enrolment
in this course or in another ITEE course and where that
code has not been shared or published.
Code (in any programming language) that you have taken
inspiration from but have not copied.
1 Version 1.0
Code Origin Usage/Referencing
Other code – includes: code provided by teaching staff only
in a previous offering of this course (e.g. previous A1 solu￾tion); code from websites; code from textbooks; any code
written by someone else, or partially written by someone
else; and any code you have written that is available to
other students.
May not be used. If the source of the code is referenced
adjacent to the code then this will be considered code
without academic merit (not misconduct) and will be
removed from your assignment prior to marking (which
may cause compilation to fail and zero marks to be
awarded). Copied code without adjacent referencing will
be considered misconduct and action will be taken.
Uploading or otherwise providing the assignment specification or part of it to a third party including online 29
tutorial and contract cheating websites is considered misconduct. The university is aware of these sites and 30
many cooperate with us in misconduct investigations. 31
The course coordinator reserves the right to conduct interviews with students about their submissions, for 32
the purposes of establishing genuine authorship. If you write your own code, you have nothing to fear from this 33
process. If you are not able to adequately explain your code or the design of your solution and/or be able to 34
make simple modifications to it as requested at the interview, then your assignment mark will be scaled down 35
based on the level of understanding you are able to demonstrate. 36
In short - Don’t risk it! If you’re having trouble, seek help early from a member of the teaching staff. 37
Don’t be tempted to copy another student’s code or to use an online cheating service. You should read and 38
understand the statements on student misconduct in the course profile and on the school web-site: https: 39
//www.itee.uq.edu.au/itee-student-misconduct-including-plagiarism 40
The publish/subscribe communication model 41
From wikipedia: 42
“In software architecture, publish-subscribe is a messaging pattern where senders of messages, called 43
publishers, do not program the messages to be sent directly to receivers, called subscribers. Instead, 44
senders categorise published messages into classes without knowledge of which subscribers, if any, 45
there may be. Similarly, subscribers express interest in one or more classes and only receive messages 46
that are of interest, without knowledge of which publishers, if any, there are.” 47
In this way, the participants in the communication are very loosely coupled - when publishing a message 48
on a given topic there is no knowledge or requirement that other participant be listening for that topic. When 49
correctly implemented, publish/subscribe can be very efficient for scaling to large numbers of participants - take 50
a look at the wikipedia page for more details if you are interested, but this is not required to complete this 51
assignment. 52
Specification – psclient 53
The psclient program provides a commandline interface that allows you to participate in the publish/subscribe 54
system as a client, connecting to the server, naming the client, subscribing to and publishing topics. psclient 55
will also output notifications when topics to which that client is subscribed, get published. 56
To fully implement this functionality, psclient will either require two threads (easiest), or if you wish you 57
may use select(). Choose whichever you prefer, as long as you achieve the required functionality. 58
Command Line Arguments 59
Your psclient program is to accept command line arguments as follows: 60
./psclient portnum name [topic] ... 61
• The mandatory portnum argument indicates which localhost port psserver is listening on – either nu- 62
merical or the name of a service. 63
• The mandatory name argument specifies the name to be associated with this client, e.g. barney 64
• Any topic arguments, if provided, are to be treated as strings which are topics to which psclient should 65
immediately subscribe after connecting to the server, e.g. news, weather 66
2 Version 1.0
• If no topic arguments are provided then psclient will connect to the server without subscribing to any 67
topics. 68
psclient behaviour 69
If insufficient command line arguments are provided then psclient should emit the following message (termi- 70
nated by a newline) to stderr and exit with status 1: 71
Usage: psclient portnum name [topic] ...
If the correct number of arguments is provided, then further errors are checked for in the order below. 72
Restrictions on the name 73
The name argument must not contain any spaces, colons, or newlines. The name argument must not be an empty 74
string. If either of these conditions is not met then psclient shall emit the following message (terminated by 75
a newline) to stderr and exit with status 2: 76
psclient: invalid name
Topic argument(s) 77
The topic arguments are optional. 78
All topic arguments must not contain any spaces, colons, or newlines. All topic arguments must also not be 79
empty strings. If either of these conditions is not met for any of the topics specified on the command line then 80
psclient shall emit the following message (terminated by a newline) to stderr and exit with status 2: 81
psclient: invalid topic
Duplicated topic strings are permitted – your program does not need to check for these but should instead 82
just attempt to subscribe multiple times. (A correctly implemented server will ignore requests to subscribe to 83
a topic that is already subscribed to.) 84
Connection error 85
If psclient is unable to connect to the server on the specified port (or service name) of localhost, it shall 86
emit the following message (terminated by a newline) to stderr and exit with status 3: 87
psclient: unable to connect to port N
where N should be replaced by the argument given on the command line. (This may be a non-numerical string.) 88
psclient runtime behaviour 89
Assuming that the commandline arguments are without errors, psclient is to perform the following actions, 90
in this order, immediately upon starting: 91
• Connect to the server on the specified port number (or service name) – see above for how to handle a 92
connection error. 93
• Provide the client’s name to the server using the ‘name’ command (see the Communication protocol section 94
for details of the name command). 95
• Send subscription requests to the server for any topics listed on the command line, in the order that they 96
were specified (see the Communication protocol section for details of the subscribe command). 97
From this point, psclient shall simply output to its stdout, any lines received over the network connection 98
from the server, without any error checking or processing. A correctly implemented psserver will only ever 99
send publication notices, however your psclient does not need to check for this. 100
Specifically – psclient is not responsible for any logic processing or error checking on messages 101
received from the server – for example if a faulty server keeps sending psclient publication messages on 102
a topic to which psclient never subscribed, or from which it has unsubscribed, psclient does not have to 103
detect this. It shall simply and blindly output those messages to stdout. 104
If the network connection to the server is closed (e.g. psclient detects EOF on the socket), then psclient 105
shall emit the following message to stderr and terminate with exit status 4: 106
3 Version 1.0
psclient: server connection terminated
Simultaneously and asynchronously, psclient shall be reading newline-terminated lines from stdin, 107
and sending those lines unmodified to the server (effectively, this interface requires the user to type in command 108
strings that are sent to the server – this simplifies the implementation of psclient dramatically). The three 109
valid message types are: 110
• pub – publish under topic . Note that s may contain spaces 111
and colons. 112
• sub – subscribe this client to topic . 113
• unsub – unsubscribe this client from future publication of . 114
Note that psclient is not required to perform any error checking on the input lines – simply send them 115
unmodified to the server. In this sense, psclient is a lot like netcat. 116
If psclient detects EOF on stdin or some other communication error, it shall close its network connection 117
to the server and terminate with exit status 0. 118
Your psclient program is not to register any signal handers nor attempt to mask or block any signals. 119
psclient example usage 120
Subscribing to a topic from the commandline, then sending an invalid publish (missing value) and then imme- 121
diately publishing on that same topic and receiving the publication notice back from the server (assuming the 122
psserver is listening on port 49152). Lines in bold face are typed interactively on the console, they are not 123
part of the output of the program: 124
$./psclient 49152 fred topic1
pub topic1
:invalid
pub topic1 value 1
fred:topic1:value 1
Subscribing to a topic interactively, publishing on it (and receiving the publication notice back from the 125
server), unsubscribing, then publishing again: 126
$./psclient 49152 fred
sub topic1
pub topic1 value1
fred:topic1:value1
unsub topic1
pub topic1 value1
Here you can see that the publishing of ‘topic1’ after subscribing, causes the client to receive the publica- 127
tion notice as expected. Then the client unsubscribes, and no notification is subsequently received despite the 128
republication of the same topic. 129
Subscribing to several topics on the command line, and having these published by other clients at some 130
point after connecting: 131
$./psclient 49152 fred topic1 topic2
...
barney:topic1:value 1
...
wilma:topic2:value:2
barney:topic2:some Value
...
unsub topic1
wilma:topic2:a String Here
...
Note that after sending the ‘unsub’ command, and assuming a correctly functioning server, we do not expect 132
this client to receive any further publication messages regarding ‘topic1’. Messages on other subscribed topics 133
will still be received. 134
4 Version 1.0
Specification – psserver 135
psserver is a networked publish/subscribe server, allowing clients to connect, name themselves, subscribe to 136
and unsubscribe from topics, and publish messages setting values for topics. All communication between clients 137
and the server is over TCP using a simple command protocol that will be described in a later section. 138
Command Line Arguments 139
Your psserver program is to accept command line arguments as follows: 140
./psserver connections [portnum] 141
In other words, your program should accept one mandatory argument (connections), and one optional 142
argument which is the port number to listen on for connections from clients. 143
The connections argument indicates the maximum number of simultaneous client connections to be per- 144
mitted. If this is zero, then there is no limit to how many clients may connect (other than operating system 145
limits which we will not test). 146
The portnum argument, if specified, indicates which localhost port psserver is to listen on. If the port 147
number is absent or zero, then psserver is to use an ephemeral port. 148
Important: Even if you do not implement the connection limiting functionality, your program must correctly 149
handle command lines which include that argument (after which it can ignore any provided value – you will 150
simply not receive any marks for that feature). 151
Program Operation 152
The psserver program is to operate as follows: 153
• If the program receives an invalid command line then it must print the message: 154
Usage: psserver connections [portnum]
to stderr, and exit with an exit status of 1. 155
Invalid command lines include (but may not be limited to) any of the following: 156
– no max connections number specified 157
– the connections argument is not a non-negative integer 158
– the port number argument (if present) is not an integer value, or is an integer value and is not either 159
zero, or in the range of 1024 to 65535 inclusive 160
– too many arguments are supplied 161
• If portnum is missing or zero, then psserver shall attempt to open an ephemeral localhost port for 162
listening. Otherwise, it shall attempt to open the specific port number. If psserver is unable to listen on 163
either the ephemeral or specific port, it shall emit the following message to stderr and terminate with 164
exit status 2: 165
psserver: unable to open socket for listening
• Once the port is opened for listening, psserver shall print to stderr the port number followed by a 166
single newline character and then flush the output. In the case of ephemeral ports, the actual port 167
number obtained shall be printed, not zero. 168
• Upon receiving an incoming client connection on the port, psserver shall spawn a new thread to handle 169
that client (see below for client thread handling). 170
• If specified (and implemented), psserver must keep track of how many active client connections exist, 171
and must not let that number exceed the connections parameter. See below on client handling threads 172
for more details on how this limit is to be implemented. 173
• Note that all error messages must be terminated by a single newline character. 174
• The psserver program should not terminate under normal circumstances, nor should it block or otherwise 175
attempt to handle SIGINT. 176
5 Version 1.0
• Note that your psserver must be able to deal with any clients using the correct communication protocol, 177
not just psclient. For example, note that a correctly implemented psclient will not attempt to publish 178
or subscribe to topics before sending the name command, however you still need to ensure that psserver 179
behaves correctly if that does happen. Testing with netcat is highly recommended. 180
Client handling threads 181
A client handler thread is spawned for each incoming connection. This client thread must then wait for commands 182
from the client, one per line, over the socket. The exact format of the requests is described in the Communication 183
protocol section below. 184
As each client sends subscribe, publish and unsubscribe commands to psserver, its client handling thread 185
will need to determine which of the currently connected clients should receive topic publication messages. 186
Due to the simultaneous nature of the multiple client connections, your psserver will need to ensure mutual 187
exclusion around any shared data structure(s) to ensure that these do not get corrupted. 188
Once the client disconnects or there is a communication error on the socket then the client handler thread 189
is to close the connection, clean up and terminate. Other client threads and the psserver program itself must 190
continue uninterrupted. 191
SIGHUP handling (Advanced) 192
Upon receiving SIGHUP, psserver is to emit (and flush) to stderr statistics reflecting the program’s operation 193
to-date, specifically 194
• Total number of clients connected (at this instant) 195
• The total number of clients that have connected and disconnected since program start 196
• The total number of successful pub requests processed (since program start) 197
• The total number of successful sub requests received (since program start) 198
• The total number of successful unsub requests received (since program start). (This does not include 199
unsubscriptions due to client disconnections.) 200
Successful requests are those that are valid and not ignored. (See the Communication protocol section for 201
details.) 202
The required format is illustrated below. 203
Listing 1: psserver SIGHUP stderr output sample
Connected clients:4
Completed clients:20
pub operations:4
sub operations:15
unsub operations:0
Note that to accurately gather these statistics and avoid race conditions, you will need some sort of mutual 204
exclusion structure protecting the variables holding these statistics. 205
Global variables are not to be used to implement signal handling. See the Hints section below for how you 206
can implement this. 207
Client connection limiting (Advanced) 208
If the connections feature is implemented and a non-zero command line argument is provided, then psserver 209
must not permit more than that number of simultaneous client connections to the server. psserver shall 210
maintain a connected client count, and if a client beyond that limit attempts to connect, it shall block, indefinitely 211
if required, until another client leaves and this new client’s connection request can be accept()ed. Clients in 212
this waiting state are not to be counted in statistics reporting – they are only counted once they have properly 213
connected. 214
6 Version 1.0
HTTP connection handling (CSSE7231 students only) 215
CSSE7231 students shall, in addition, implement a simple HTTP server in their psserver implementation. 216
Upon startup, psserver shall check the value of the environment variable A4_HTTP_PORT. If set, then psserver 217
shall also listen for connections on that port number (or service name). 218
If psserver is unable to listen on that port or service name then it shall emit the following message to 219
stderr and terminate with exit status 3: 220
psserver: unable to open HTTP socket for listening
The ability to listen on this port is checked after the ability to listen on the “main” port (i.e. the one given 221
on the command line). If the A4_HTTP_PORT environment variable is not set then psserver shall not listen on 222
any additional ports and shall not handle these HTTP connections. 223
The communication protocol uses HTTP. The connecting program (e.g. netcat, or a web browser) shall 224
send HTTP requests and psserver shall send HTTP responses as described below. The connection between 225
client and server is kept alive between requests. Multiple HTTP clients may be connected simultaneously. 226
Additional HTTP header lines beyond those specified may be present in requests or responses and must be 227
ignored by the respective server/client. Note that interaction between a client on the HTTP port and psserver 228
is synchronous – any one client can only have a single request underway at any one time. This greatly simplifies 229
the implementation of the psserver HTTP connection handling threads. 230
The only supported request method is a GET request in the following format: 231
• Request: GET /stats HTTP/1.1 232
– Description: the client is requesting statistics from psserver 233
– Request 234
∗ Request Headers: none expected, any headers present will be ignored by psserver. 235
∗ Request Body: none, any request body will be ignored 236
– Response 237
∗ Response Status: 200 (OK). 238
∗ Response Headers: the Content-Length header with correct value is required (number of bytes 239
in the response body), other headers are optional. 240
∗ Response Body: the ASCII text containing the same psserver statistics information described 241
in the SIGHUP handling section above. 242
If psserver receives an invalid HTTP request then it should close the connection to that requestor (and 243
terminate the thread associated with that connection). Similarly, if a HTTP client disconnects, psserver should 244
handle this gracefully and terminate the thread associated with the connection. 245
Program output 246
Other than error messages, the listening port number, and SIGHUP-initiated statistics output, psserver is not 247
to emit any output to stdout or stderr. 248
Server data structures 249
While the publish/subscribe model is conceptually simple, its implementation in a multithreaded server is not 250
trivial. This section provides some hints and guidance on how to architect psserver to keep it manageable. 251
Start by noting that psserver maintains one thread per connected client (call it the client-handler thread), 252
however when a client sends a publish message to its handler thread, somehow that thread must identify all 253
of the currently-connected clients that are subscribed to this topic. 254
For this you will clearly need a data structure that is accessible to all threads (and protected by mutual 255
exclusion appropriately). But how should that structure be organised? 256
What we recommend, and are somewhat encouraging with the stringmap library and API that is part of 257
this assignment (see the stringmap API section below), is as follows: 258
• Create a data structure to manage information about a specific client – its name, the file descriptor or 259
FILE* handles used to talk to it and so on. Let’s call this struct Client. A new one of these gets created 260
and populated each time a new client connects. 261
7 Version 1.0
• Create another data structure that can manage a collection of these struct Client (or rather, pointers 262
to them) – it could be a linked list, or a dynamically allocated array, or however it makes most sense to 263
you to implement. You need at least to be able to add, remove and iterate through the pointers to struct 264
Client that are stored in this data structure. 265
• Once you can successfully manage collections of clients, you can use the stringmap API described below 266
– this is a data structure that allows you to define mappings between strings and void * pointers. If you 267
treat topics as stringmap keys, and the client collection data structure as the associated item then you 268
get a nice way of identifying which clients are subscribed to which topics. When you need to publish a 269
topic, you should retrieve the collection of subscribed clients from the stringmap, iterate through it and 270
send the message to each one in turn. Note that in this case it is the client thread that receives a message 271
that does the sending to all clients that are subscribed to that topic. Don’t forget the mutual exclusion – 272
you don’t want another thread making changes to this while you are iterating! 273
You don’t have to implement psserver this way, however if you want maximum marks you do have to 274
implement the stringmap API anyway, so you might as well use it in your solution. 275
Communication protocol 276
The communication protocol between clients and psserver uses simple newline-terminated text message strings 277
as described below. Messages from client to server are space delimited. Messages from server to client are colon 278
delimited. Note that the angle brackets are used to represent placeholders, and are not part of the 279
command syntax. 280
Supported messages from psclient to psserver are: 281
• name – the client is naming itself 282
• sub – the client is subscribing to , i.e. wishes to receive any future publication notifica- 283
tions on this topic 284
• unsub – the client is unsubscribing from and should no longer receive publication 285
messages 286
• pub – the client is publishing to the the given . Any clients (including 287
this one) that are subscribed to this topic, should receive a publication message 288
Single spaces are used as separators between fields but note that the field in a pub message may 289
contain spaces (and colons). 290
Supported messages from psserver to psclient are 291
• :invalid – sent by the server to a client if the server receives an invalid command from that client (see 292
below) 293
:: – sent by the server to all connected clients that have subscribed to topic. 294
The name is the name of the client that published the message. Note that the field may contain 295
colons (and spaces). 296
Invalid commands that might be received by psserver from a client include: 297
• Invalid command word – an empty string or a command word which is not pub, sub, name or unsub 298
• Invalid arguments such as empty strings (for any field) or names or topics containing spaces or colons 299
• Too few or too many arguments 300
• Any other kind of malformed message 301
psserver shall send a :invalid response to a client on receipt of an invalid command. 302
Other requirements are as follows: 303
• psserver shall ignore any name command coming from a client that has already provided a name. 304
• psserver shall ignore duplicate subscription requests from a client (i.e. if a client subscribes more than 305
once to a given topic it will only ever receive one copy of matching messages). 306
8 Version 1.0
• psserver shall ignore unsub requests from a client on a topic that the client is not subscribed to. 307
• psserver shall ignore any commands coming from a client before that client has named itself. Anonymous 308
clients may neither subscribe to nor publish topics. 309
Note that these are not “invalid” commands – they are well-formed commands that will just be ignored by 310
psserver. 311
Note that psserver shall not attempt to detect or reject simultaneous duplicated names from multiple 312
clients (e.g. two clients trying to call themselves fred). Such behaviour is undefined and will not be tested1
. 313
The only exception to the duplicated name restriction is that a name may be reused by a client from connection to 314
connection – i.e. a client connects, calls itself fred, interacts with the server for some time and then disconnects. 315
Later, if another client connects, then it may reuse the name fred. 316
The stringmap library and API 317
An API (Application Programming Interface) for the data structure implementation known as ‘stringmap’ is pro- 318
vided to you in the form of a header file, found on moss in /local/courses/csse2310/include/stringmap.h. 319
An implementation of stringmap is also available to you on moss, in the form of a shared library file 320
(/local/courses/csse2310/lib/libstringmap.so). This will allow you to start writing psserver without 321
first implementing the stringmap API. 322
However, to receive full marks you must implement your own version of stringmap according to 323
the API specified by stringmap.h. You must submit your stringmap.c and your Makefile must build this to 324
your own libstringmap.so. 325
Your psserver must use this API and link against libstringmap.so. Note that we will use our 326
libstringmap.so when testing your psserver so that you are not penalised in the marking of psserver for any 327
bugs in your stringmap implementation. You are free to use your own libstringmap.so when testing yourself 328
– see below. 329
stringmap.h defines the following functions and types: 330
Listing 3: stringmap.h contents
#ifndef STRINGMAP_H
#define STRINGMAP_H
typedef struct StringMap StringMap;
// data structure stored in the StringMap
typedef struct {
char *key;
void *item;
} StringMapItem;
// Allocate, initialise and return a new, empty StringMap
StringMap *stringmap_init(void);
// Free all memory associated with a StringMap.
// frees stored key strings but does not free() the (void *)item pointers
// in each StringMapItem
void stringmap_free(StringMap *sm);
// Search a stringmap for a given key, returning a pointer to the entry
// if found, else NULL
void *stringmap_search(StringMap *sm, char *key);
// Add an item into the stringmap, return 1 if success else 0 (e.g. already present)
// the 'key' string is copied before being stored in the stringmap
// The item pointer is stored as-is, no attempt is made to copy its contents
int stringmap_add(StringMap *sm, char *key, void *item);
1you can implement this if you want but it won’t be easy or pretty, nor will it get you any marks
9 Version 1.0
// Removes an entry from a stringmap
// free()s the StringMapItem and the copied key string, but not
// the item pointer.
// returns 1 if success else 0 (e.g. item not present)
int stringmap_remove(StringMap *sm, char *key);
// Iterate through the stringmap - if prev is NULL then the first entry is returned
// otherwise prev should be a value returned from a previous call to stringmap_iterate()
// This operation is not thread-safe - any changes to the stringmap between successive
// calls to stringmap_iterate may result in undefined behaviour.
// returns NULL if no more items to examine
StringMapItem *stringmap_iterate(StringMap *sm, StringMapItem *prev);
#endif
Note that it is not expected that your stringmap library be thread safe – the provided libstringmap.so is 331
not. 332
For example code that shows how to use the stringmap API see 333
/local/courses/csse2310/resources/a4/stringmaptest.c on moss. If you copy this file to one of your own 334
directories then you can build it with the command: 335
gcc -I/local/courses/csse2310/include -L/local/courses/csse2310/lib -lstringmap 336
stringmaptest.c -o stringmaptest 337
Creating shared libraries – libstringmap.so 338
This section is only relevant if you are creating your own implementation of libstringmap.o. 339
Special compiler and linker flags are required to build shared libraries. Here is a Makefile fragment you can 340
use to turn stringmap.c into a shared library, libstringmap.so: 341
Listing 4: Makefile fragment to compile and build a shared library
CC=gcc
LIBCFLAGS=-fPIC -Wall -pedantic -std=gnu99
# Turn stringmap.c into stringmap.o
stringmap.o: stringmap.c
$(CC) $(LIBCFLAGS) -c $<
# Turn stringmap.o into shared library libstringmap.so
libstringmap.so: stringmap.o
$(CC) -shared -o $@ stringmap.o
stringmap.h should only be listed as a dependency in your Makefile if you have a local copy in your repository. 342
This is not required, but if you do include a copy of stringmap.h in your submission then it must be styled 343
correctly. 344
Running psserver with your libstringmap.so library 345
The shell environment variable LD_LIBRARY_PATH specifies the path (set of directories) searched for shared li- 346
braries. On moss, by default this includes /local/courses/csse2310/lib, which is where the provided libraries 347
libcsse2310a4.so and our implementation of libstringmap.so live. 348
If you are building your own version and wish to use it when you run psserver, then you’ll need to make 349
sure that your version of libstringmap.so is used. To do this you can use the following: 350
LD_LIBRARY_PATH=.:${LD_LIBRARY_PATH} ./psserver 351
This commandline sets the LD_LIBRARY_PATH just for this specific run of psserver, causing it to 352
dynamically link against your version of libstringmap.so in the current directory instead of the one we have 353
provided. 354
Note that we will use our libstringmap.so when testing your psserver unless you statically link your 355
stringmap into your psserver. Your libstringmap.so will be tested independently. 356
10 Version 1.0
Provided Libraries 357
libstringmap 358
See above. This must be linked with -L/local/courses/csse2310/lib -lstringmap. It is recommended not 359
to statically link your own stringmap.o into your psserver or hardwire the path to libstringmap.so. If you 360
wish to test your own libstringmap.so then you can use the approach described above. 361
libcsse2310a4 362
A split_by_char() function is available to break a line up into multiple parts, e.g. based on spaces. This is 363
similar to the split_line() function from libcsse2310a3 though allows a maximum number of fields to be 364
specified. 365
Several additional library functions have been provided to aid CSSE7231 students in parsing/construction 366
of HTTP requests/responses. The functions in this library are: 367
char** split_by_char(char* str, char split, unsigned int maxFields);
int get_HTTP_request(FILE *f, char **method, char **address,
HttpHeader ***headers, char **body);
char* construct_HTTP_response(int status, char* statusExplanation,
HttpHeader** headers, char* body);
int get_HTTP_response(FILE *f, int* httpStatus, char** statusExplain,
HttpHeader*** headers, char** body);
void free_header(HttpHeader* header);
void free_array_of_headers(HttpHeader** headers);
These functions and the HttpHeader type are declared in /local/courses/csse2310/include/csse2310a4.h 368
on moss and their behaviour is described in man pages on moss – see split_by_char(3), get_HTTP_request(3), 369
and free_header(3). 370
To use these library functions, you will need to add #include to your code and use the 371
compiler flag -I/local/courses/csse2310/include when compiling your code so that the compiler can find 372
the include file. You will also need to link with the library containing these functions. To do this, use the 373
compiler arguments -L/local/courses/csse2310/lib -lcsse2310a4 374
(You only need to specify the -I and -L flags once if you are using multiple libraries from those locations, 375
e.g. both libstringmap and libcsse2310a4.) 376
libcsse2310a3 377
You are also welcome to use the "libcsse2310a3" library from Assignment 3 if you wish. This can be linked with 378
-L/local/courses/csse2310/lib -lcsse2310a3. Note that split_space_not_quote() is not appropriate for 379
use in this assignment – quotes have no particular meaning in the communication protocol for psserver. 380
Style 381
Your program must follow version 2.2 of the CSSE2310/CSSE7231 C programming style guide available on the 382
course Blackboard site. Note that, in accordance with the style guide, function comments are not expected in 383
your stringmap.c for functions that are declared and commented in stringmap.h. 384
Hints 385
1. Review the lectures related to network clients, HTTP, threads and synchronisation and multi-threaded 386
network servers. This assignment builds on all of these concepts. 387
11 Version 1.0
2. You can test psclient and psserver independently using netcat as demonstrated in the lectures. You 388
can also use the provided demo programs demo-psclient and demo-psserver. 389
3. The read_line() function from libcsse2310a3 may be useful in both psclient and psserver 390
4. The multithreaded network server example from the lectures can form the basis of psserver. 391
5. Use the provided library functions (see above). 392
6. Consider the strchr() function to search a string for a particular character (e.g. colon). 393
7. Consider a dedicated signal handling thread for SIGHUP. pthread_sigmask() can be used to mask signal 394
delivery to threads, and sigwait() can be used in a thread to block until a signal is received. You will 395
need to do some research and experimentation to get this working. 396
Forbidden Functions 397
You must not use any of the following C functions/statements. If you do so, you will get zero (0) marks for the 398
assignment. 399
• goto 400
• longjmp() and equivalent functions 401
• system() 402
• mkfifo() or mkfifoat() 403
• POSIX regex functions 404
• fork(), pipe(), popen(), execl(), execvp() and other exec family members. 405
Submission 406
Your submission must include all source and any other required files (in particular you must submit a Makefile). 407
Do not submit compiled files (eg .o, compiled programs) or test files. You are not expected to submit 408
stringmap.h. If you do so, it will be marked for style. 409
Your programs (named psclient and psserver) and your stringmap library (named libstringmap.so if 410
you implement it) must build on moss.labs.eait.uq.edu.au with: 411
make 412
If you only implement one or two of the programs/library then it is acceptable for make to just build those 413
programs/library – and we will only test those programs/library. 414
Your programs must be compiled with gcc with at least the following switches (plus applicable -I options 415
etc. – see Provided Libraries above): 416
-pedantic -Wall -std=gnu99 417
You are not permitted to disable warnings or use pragmas to hide them. You may not use source files other 418
than .c and .h files as part of the build process – such files will be removed before building your program. 419
If any errors result from the make command (e.g. an executable can not be created) then you will receive 420
0 marks for functionality (see below). Any code without academic merit will be removed from your program 421
before compilation is attempted (and if compilation fails, you will receive 0 marks for functionality). 422
Your program must not invoke other programs or use non-standard headers/libraries (besides those we have 423
provided for you to use). 424
Your assignment submission must be committed to your subversion repository under 425
https://source.eait.uq.edu.au/svn/csse2310-sem2-sXXXXXXX/trunk/a4 426
where sXXXXXXX is your moss/UQ login ID. Only files at this top level will be marked so do not put source 427
files in subdirectories. You may create subdirectories for other purposes (e.g. your own test files) but these 428
will not be considered in marking – they will not be checked out of your repository. 429
You must ensure that all files needed to compile and use your assignment (including a Makefile) are commit- 430
ted and within the trunk/a4 directory in your repository (and not within a subdirectory) and not just sitting 431
12 Version 1.0
in your working directory. Do not commit compiled files or binaries. You are strongly encouraged to check out 432
a clean copy for testing purposes – the reptesta4.sh script will do this for you. 433
To submit your assignment, you must run the command 434
2310createzip a4 435
on moss and then submit the resulting zip file on Blackboard (a GradeScope submission link will be made 436
available in the Assessment area on the CSSE2310/7231 Blackboard site)2
. The zip file will be named 437
sXXXXXXX_csse2310_a4_timestamp.zip 438
where sXXXXXXX is replaced by your moss/UQ login ID and timestamp is replaced by a timestamp indicating 439
the time that the zip file was created. 440
The 2310createzip tool will check out the latest version of your assignment from the Subversion repository, 441
ensure it builds with the command ‘make’, and if so, will create a zip file that contains those files and your 442
Subversion commit history and a checksum of the zip file contents. You may be asked for your password as part 443
of this process in order to check out your submission from your repository. 444
You must not create the zip file using some other mechanism and you must not modify the zip file prior 445
to submission. If you do so, you will receive zero marks. Your submission time will be the time that the file 446
is submitted via GradeScope on Blackboard, and not the time of your last repository commit nor the time of 447
creation of your submission zip file. 448
We will mark your last submission, even if that is after the deadline and you made submissions before the 449
deadline. Any submissions after the deadline3 will incur a late penalty – see the CSSE2310/7231 course profile 450
for details. 451
Marks 452
Marks will be awarded for functionality and style and documentation. Marks may be reduced if you are asked 453
to attend an interview about your assignment and you are unable to adequately respond to questions – see the 454
Student conduct section above. 455
Functionality (60 marks) 456
Provided your code compiles (see above) and does not use any prohibited statements/functions (see above), 457
and your zip file has not been modified prior to submission, then you will earn functionality marks based on 458
the number of features your program correctly implements, as outlined below. Partial marks will be awarded 459
for partially meeting the functionality requirements. Not all features are of equal difficulty. If your program 460
does not allow a feature to be tested then you will receive 0 marks for that feature, even if you 461
claim to have implemented it. Reasonable time limits will be applied to all tests. If your program takes longer 462
than this limit, then it will be terminated and you will earn no marks for the functionality associated with that 463
test. 464
Exact text matching of files and output (stdout and stderr) is used for functionality marking. 465
Strict adherence to the output format in this specification is critical to earn functionality marks. 466
The markers will make no alterations to your code (other than to remove code without academic merit). 467
Note that your client and server will be tested independently. 468
Marks will be assigned in the following categories. There are 10 marks for libstringmap.o, 10 marks for 469
psclient and 40 marks (CSSE2310) or 50 marks (CSSE7231) for psserver. 470
1. libstringmap – correctly create and free memory associated with a stringmap object (3 marks) 471
2. libstringmap – correctly add and retrieve items (3 marks) 472
3. libstringmap – correctly delete items (2 marks) 473
4. libstringmap – correctly iterate through a stringmap (2 marks) 474
475
5. psclient correctly handles invalid command lines (including invalid names and topics) (2 marks) 476
2You may need to use scp or a graphical equivalent such as WinSCP, Filezilla or Cyberduck in order to download the zip file to
your local computer and then upload it to the submission site.
3or your extended deadline if you are granted an extension.
13 Version 1.0
6. psclient connects to server and also handles inability to connect to server (2 marks) 477
7. psclient correctly sends the required name and sub commands upon startup (2 marks) 478
8. psclient correctly displays lines received from the server and sends input lines to the server (2 marks) 479
9. psclient correctly handles communication failure (2 marks) 480
481
10. psserver correctly handles invalid command lines (3 marks) 482
11. psserver correctly listens for connections and reports the port 483
(including inability to listen for connections) (3 marks) 484
12. psserver correctly handles invalid command messages (5 marks) 485
13. psserver correctly handles subscription and publication requests (8 marks) 486
14. psserver correctly handles unsubscription requests (5 marks) 487
15. psserver correctly handles multiple simultaneous client connections using threads 488
(including protecting data structures with mutexes) (5 marks) 489
16. psserver correctly handles disconnecting clients and communication failure (3 marks) 490
17. psserver correctly implements client connection limiting (4 marks) 491
18. psserver correctly implements SIGHUP statistics reporting (4 marks) 492
493
19. (CSSE7231 only) psserver correctly listens on the port specified by A4_HTTP_PORT 494
(and handles inability to listen or environment variable not set) (3 marks) 495
20. (CSSE7231 only) psserver correctly responds to HTTP requests (including invalid requests) 496
from a single client issuing one request per connection (4 marks) 497
21. (CSSE7231 only) psserver supports multiple simultaneous HTTP clients and multiple 498
sequential requests over each connection (3 marks) 499
Some functionality may be assessed in multiple categories, e.g. it is not possible test the handling of unsubscrip- 500
tion messages without being able to publish messages. Note that the ability to support multiple simultaneous 501
clients will be covered in multiple categories. Category 15 is about using threads and ensuring data structures 502
are protected. 503
Style Marking 504
Style marking is based on the number of style guide violations, i.e. the number of violations of version 2.2 of 505
the CSSE2310/CSSE7231 C Programming Style Guide (found on Blackboard). Style marks will be made up of 506
two components – automated style marks and human style marks. These are detailed below. 507
You should pay particular attention to commenting so that others can understand your code. The marker’s 508
decision with respect to commenting violations is final – it is the marker who has to understand your code. To 509
satisfy layout related guidelines, you may wish to consider the indent(1) tool. Your style marks can never be 510
more than your functionality mark – this prevents the submission of well styled programs which don’t meet at 511
least a minimum level of required functionality. 512
You are encouraged to use the style.sh tool installed on moss to style check your code before submission. 513
This does not check all style requirements, but it will determine your automated style mark (see below). Other 514
elements of the style guide are checked by humans. 515
All .c and .h files in your submission will be subject to style marking. This applies whether they are 516
compiled/linked into your executable or not4
. 517
4Make sure you remove any unneeded files from your repository, or they will be subject to style marking.
14 Version 1.0
Automated Style Marking (5 marks) 518
Automated style marks will be calculated over all of your .c and .h files as follows. If any of your submitted 519
.c and/or .h files are unable to be compiled by themselves then your automated style mark will be zero (0). 520
(Automated style marking can only be undertaken on code that compiles. The provided style.sh script checks 521
this for you.) 522
If your code does compile then your automated style mark will be determined as follows: Let 523
• W be the total number of distinct compilation warnings recorded when your .c files are individually built 524
(using the correct compiler arguments) 525
• A be the total number of style violations detected by style.sh when it is run over each of your .c and 526
.h files individually5
. 527
Your automated style mark S will be 528
S = 5 − (W + A) 529
If W +A ≥ 5 then S will be zero (0) – no negative marks will be awarded. Note that in some cases style.sh 530
may erroneously report style violations when correct style has been followed. If you believe that you have been 531
penalised incorrectly then please bring this to the attention of the course coordinator and your mark can be 532
updated if this is the case. Note also that when style.sh is run for marking purposes it may detect style 533
errors not picked up when you run style.sh on moss. This will not be considered a marking error – it is your 534
responsibility to ensure that all of your code follows the style guide, even if styling errors are not detected in 535
some runs of style.sh. 536
Human Style Marking (5 marks) 537
The human style mark (out of 5 marks) will be based on the criteria/standards below for “comments”, “naming” 538
and “other”. The meanings of words like appropriate and required are determined by the requirements in the 539
style guide. Note that functions longer than 50 lines will be penalised in the automated style marking. Functions 540
that are also longer than 100 lines will be further penalised here. 541
Comments (2.5 marks) 542
Mark Description
0
The majority (50%+) of comments present are inappropriate OR there are many required comments
missing
0.5 The majority of comments present are appropriate AND the majority of required comments are
present
1.0 The vast majority (80%+) of comments present are appropriate AND there are at most a few missing
comments
1.5 All or almost all comments present are appropriate AND there are at most a few missing comments
2.0 Almost all comments present are appropriate AND there are no missing comments
2.5 All comments present are appropriate AND there are no missing comments
543
Naming (1 mark) 544
Mark Description
0 At least a few names used are inappropriate
0.5 Almost all names used are appropriate
1.0 All names used are appropriate
545
5Every .h file in your submission must make sense without reference to any other files, e.g., it must #include any .h files that
contain declarations or definitions used in that .h file.
15 Version 1.0
Other (1.5 marks) 546
Mark Description
0
One or more functions is longer than 100 lines of code OR there is more than one global/static
variable present inappropriately OR there is a global struct variable present inappropriately OR
there are more than a few instances of poor modularity (e.g. repeated code)
0.5 All functions are 100 lines or shorter AND there is at most one inappropriate non-struct global/static
variable AND there are at most a few instances of poor modularity
1.0
All functions are 100 lines or shorter AND there are no instances of inappropriate global/static
variables AND there is no or very limited use of magic numbers AND there is at most one instance
or poor modularity
1.5 All functions are 100 lines or shorter AND there are no instances of inappropriate global/static
variables AND there is no use of magic numbers AND there are no instances of poor modularity
547
SVN commit history assessment (5 marks) 548
Markers will review your SVN commit history for your assignment up to your submission time. This element 549
will be graded according to the following principles: 550
• Appropriate use and frequency of commits (e.g. a single monolithic commit of your entire assignment will 551
yield a score of zero for this section) 552
• Appropriate use of log messages to capture the changes represented by each commit. (Meaningful messages 553
explain briefly what has changed in the commit (e.g. in terms of functionality) and/or why the change 554
has been made and will be usually be more detailed for significant changes.) 555
The standards expected are outlined in the following rubric: 556
Mark
(out of 5) Description
0
Minimal commit history – single commit OR
all commit messages are meaningless.
1
Some progressive development evident (more than one commit) OR
at least one commit message is meaningful.
2
Some progressive development evident (more than one commit) AND
at least one commit message is meaningful.
3
Progressive development is evident (multiple commits) AND
at least half the commit messages are meaningful.
4
Multiple commits that show progressive development of all functionality AND
meaningful messages for most commits.
5
Multiple commits that show progressive development of all functionality AND
meaningful messages for ALL commits.
557
Total Mark 558
Let 559
• F be the functionality mark for your assignment (out of 60 for CSSE2310, or 70 for CSSE7231). 560
• S be the automated style mark for your assignment (out of 5). 561
• H be the human style mark for your assignment (out of 5) 562
• C be the SVN commit history mark (out of 5) 563
Your total mark for the assignment will be: 564
M = F + min{F, S + H} + min{F, C} 565
out of 75 (for CSSE2310 students) or 85 (for CSSE7231 students). 566
In other words, you can’t get more marks for style or SVN commit history or documentation than you do 567
for functionality. Pretty code that doesn’t work will not be rewarded! 568
16 Version 1.0
Late Penalties 569
Late penalties will apply as outlined in the course profile. 570
Specification Updates 571
Any errors or omissions discovered in the assignment specification will be added here, and new versions released 572
with adequate time for students to respond prior to due date. Potential specification errors or omissions can be 573
discussed on the discussion forum or emailed to csse2310@uq.edu.au. 574
17 Version 1.0
联系我们
  • QQ:99515681
  • 邮箱:99515681@qq.com
  • 工作时间:8:00-21:00
  • 微信:codinghelp
热点标签

联系我们 - QQ: 99515681 微信:codinghelp
程序辅导网!