CSCI4061 Project2: Multi-ProcessChatApp solved

$29.99

Original Work ?
Category: You will Instantly receive a download link for .ZIP solution file upon Payment

Description

5/5 - (1 vote)

1 Introduction This lab focuses on three OS system concepts. First, the use of processes to decompose an application and to provide isolation (i.e. processors can fail independently without impact). Second, the use of interprocess communication (or IPC) to coordinate and communicate among the processes. Third, the use of “polling” to implement asynchrony in the absence of threads. To gain experience with these concepts, you will implement a simple ”local” multi-party chat application using a multi-process architecture. Note that a real chat program would be client/server and span many machines. In contrast, the chat processes in our solution will all run on a single machine ”locally”. Your chat-service will have a central chat server, which handles all of the management of the chat, and waits for ”users” to connect to the server, supporting both private peer-to-peer chatting and group chatting. The chat group will contain all users that are connected to the server and only one such group will be supported at a time. In this architecture, isolation via processes is very important as users need to be completely isolated from each. Users may join and leave the chat, or their chat code may fail unpredictably, but the chat service should keep running until the chat server decides otherwise. To enable communication, you will use UNIX pipes as we will describe.
2 Description Our chat service will be provided on single centralized server. When a user wishes to chat, they connect to the central server. The server process then creates an associated child process the user, through which users will be participating in the chat. You will design such a multi-process chat application in this assignment, given initial code. Your chat application will consist of one main parent process (called the SERVER process) and several child processes that each communicate with their associated user process. There is a unique child process for each connected user. The SERVER process will have zero or more child processes corresponding to each user currently connected to the chat server.
2.1 SERVERprocess TheSERVERprocessisthemainparentprocess,whichwillrunwhenthechatserverprogramisstarted. Itisresponsible for forking child processes for each user. The SERVER process provides an interface for following administrative functions listed below. 1. \list : List all of the users currently connected to the server. Print ’’ if there are no users currently. 2. \kick : Kick the specified user off the chat session. 3. \exit : Terminate all user sessions and close the chat server as well. 4. : Broadcastthistexttoalloftheuserprocesseswithprefix,“admin:”. Donothing,ifnousers are connected to the chat. The users will print out the message. admin:
2.2 USERprocess The user process is another program that you will write to provide an interface to the server in the chat. When a user startsaUSERprocess,thiswillconnecttotheSERVERandinteractwithSERVERgivenapipe. Wewillprovidethe code for the initial communication between the SERVER and USER processes. The USER process must display the name of the user as part of the prompt. The USER process will have some commands of its own. All the user commands are listed below.
1
Centralized Server
Child Process
Child Process
Child Process
. . .
USER Process
USER Process
USER Process (MAX_USER = 10)
Given code
Figure 1: IPC among various SERVER and USERs processes.
1. \list : Same as in the SERVER process. Output should be printed in the user’s process terminal window. 2. \exit : Disconnect this user. Terminate the USER process and remove them from the chat session. 3. \p2p : Send a personal message () to the user specified in . Print error if the user is invalid. 4. : Same as in the SERVER process but without a prefix. Broadcast this text to all user processes.
3 FormsofIPC You will implement pipe communication (between processes) for this multi-process chat application. For each pair of communicating processes, you will have a read pipe and a write pipe asintheknock-knockexampleinclass. Fig. 1 demonstrates the IPC among the different processes. There are different kinds of messages exchanged among the various processes, corresponding to various commands described in the previous section. The centralized SERVER process waits for user connections. When a USER process connects to the SERVER, the SERVER creates two pipes to communicatewith the user and another two pipesto communicate with the associated childprocess. The SERVER, then creates this child process that will communicate with the user. The role of child processes is to forward messages between SERVER and USERS processes. USER processes do not communicate with the SERVER process directly but only to the associated child process. An exception is the initial connection from the USERS to the SERVER. We will provide code for this initial communication between a USER and the SERVER. For each of the user commands entered from a user, a message will be sent to the corresponding child process whichthensendsittotheSERVER.TheSERVERwillprocessthecommandandsendtheresulttothecorresponding child process via pipes. Finally, the result will be sent to USER via pipes written by the associated child process. The user then outputs the result to the terminal. For instance, if the \p2p command is used, the SERVER will parse the command string to figure out the destination user and its child process. Then, it sends the message to that user using the appropriate child process pipe.
4 ProgramFlow: This section describes the flow of each of the involved processes.
2
4.1 SERVERProcess: When you invoke your server, the main() function of your program starts executing. Upon its invocation, the SERVER process performs the following tasks:
1. Waiting for connections from users : (a) The SERVER will call setup connection(char * server id). You will need to pass your own server id to set up the SERVER and your USER will use it to connect to the SERVER. (b) The SERVER then polls (via non-blocking get connection(char * user id, int pipe child writing to user[2], int pipe child reading from user[2])) to check for a new user connection. The get connection() returns −1 if there is no new user connection. In the get connection function, two pipe arrays are internally created. You need to pass the two pipe arrays as parameters. (c) Once the SERVER gets a new connection, the SERVER needs to create two pipes for bidirectional communication with a child process and it creates a child process. (d) In a child process, the child process will have four pipes in total, i.e., two pipes for bidirectional communication with a user and two pipes for bidirectional communication with the SERVER. 2. Processing server commands : (a) TheSERVERwillgetinputforadministratorcommands. Tothisend,theSERVERpolls(vianon-blocking read) from stdin (0). (b) You will need to use fcntl function to make stdin NON BLOCKING: fcntl(0, F SETFL, fcntl(0, F GETFL)|O NONBLOCK); (c) The non-blocking read will read data from stdin. If no data is available, the read system call will return immediately with return value of−1 and errno set to EAGAIN. In that case, simply continue the polling. (d) If read returns with some data, read the data into a buffer and handle the command. There are four types of commands that the SERVER process may read from stdin. i. \list : When this command is received, the SERVER creates a string with the names of all the active users and prints them. Print ’’ if there are no users currently. ii. \kick : This command will be used to terminate a particular user’s session. The SERVERshouldterminatethesessionforthisuserby killingitschildprocess. Thisusershouldbe removed from the user list as well. Care should be taken to clean-up the user’s pipes and any zombie processes as well. iii. \exit : The SERVER should cleanup all of the users, terminate all their processes, and cleanup their pipes and wait for all child processes to terminate. Each child process should cleanup the pipes for a user and exit. iv. : Anyothertextenteredshouldbesenttoalltheactiveusers’pipeswiththeprefix, “Notice:”. All users’ processes should print out this text as is. 3. Processing user commands : (a) The SERVER then polls (via non-blocking read) on the set of open pipe file descriptors created when forking the child process, in a loop. There might be no child process at this stage if there is no users. The termination condition for the loop is when the server’s exit command is used on the SERVER process. (b) Thenon-blockingreadwillreaddatafromthepipe. Ifnodataisavailable,theread systemcallwillreturn immediately with return value of −1 and errno set to EAGAIN. In that case, simply continue with the polling. To reduce CPU consumption in the loop, you will use usleep between reads. Put this in yourloopsASAP.
3
(c) If read returns with some data, read the data into a buffer. There are four types of messages that the SERVER process may read from the child processes pipe. i. \list : Same as above. The list of active users will be generated and sent to the requester via the child process’ pipe. The user process should print this list. Print ’’ if there are no users currently. ii. \p2p : This command is used by a user to send messages to a particular user. Whenthiscommandisreceived,theSERVERshouldsearchforthespecifieduserinitsuserlist, extract the message from the command string and send it to the addressed user through a pipe write. An error should be printed in the appropriate window if the username does not exist. iii. \exit: Whenthiscommandisusedonauser’sprocess,theSERVERshouldclean-upthatuser,remove it from the user list, terminate the child process associated to the user, and cleanup the corresponding pipes. iv. : Any other text entered should be sent to all the active users. All the users’ processes should print out this text as is (prefixed by the sending user).
4.2 ChildProcess: 1. As explained, the role of the child process is to forward messages between SERVER and USERS processes. Child process will poll (via non-blocking read) on the pipe for an associated user and the SERVER. 2. If read returns with some data, read the data into a buffer and forward it to SERVER or USERS through the correct pipes.
4.3 UserProcess: 1. The user process starts by calling connect to server(char server id, char * user id, int pipe user reading from server[2], int pipe user writing to server[2]). This function will return -1, if the connection failed. You need to pass the server id to connect to the SERVER. You will need to pass the user id (on the command line) to be used for the chat when the user process is started. Lastly, you need to pass two pipe arrays as parameters to obtain pipes that will be used for communicating with SERVER. 2. Forusercommands,auserprocesspolls(vianon-blockingread)fromstdin(0)asdoneintheSERVERprocess commands. 3. If read returns with some data, the process will read the data into a buffer. Then, it will send data to the child process through pipe user writing to server. 4. The commands that a user can send, are list, p2p, exit, and , as explain in previous section. 5. The user process then polls (via non-blocking read) on pipe from server to read data from an associated child process. Again, to reduce CPU consumption in the loop, you will use usleep between reads. 6. If read returns with some data from the child process, it will be printed out.
5 ErrorHandling: Youareexpectedtocheckthereturnvalueofallsystemcallsthatyouuseinyourprogramtocheckforerrorconditions. If your program encounters an error (for example, if an invalid user name is supplied in the \p2p command), a useful error message should be printed to the screen. If any error prevents your program from functioning normally, then it should exit after printing the error message. (The use of the perror() function for printing error messages is encouraged.) Upon executing the\exit command on the SERVER, the main SERVER process and its child processes (if exist) must exit properly, cleaning-up all of the users, waiting for all child processes and freeing up any used resources.
4
6 ExtraCredit: Handlecrashfailures, e.g. acontrol-ccanbehitinaUSERorSERVERwindow. Ifthishappens, handleit. Acrashed USERshould be cleanedupand not disruptthe SERVER. Acrashed SERVERshould allowevery USER to terminate automaticaly. Think about how you can detect failure via pipes. Be careful to take care of zombie or/and orphaned processes. Addanothercommand: \seg–createasegmentationfaultintheuserprocessbyanymeans(e.g. char*n= NULL; *n = 1;). The result of this should be that the SERVER cleans up that user and otherwise the chat should run smoothly. ALLof these must be implemented for extra-credit.
7 ImplementationNotes: Some useful items. 1. Remember that the SERVER and USER processes must be running on the same machine. 2. We will be providing most of the nitty-gritty C/parsing type code. 3. To kill a process, use the kill system call. 4. When you create/get pipes remember to close the ends that the process does not need. 5. Don’t forget to remove a new line (\n) when you read inputs from stdin. 6. Hint: Thereadwillreturn0ifthepipeisclosed(broken). Youwillneedtocheckthisreturnvaluetodetectifthe user or server processes are failed (terminated). Youmustclosepipesappropriately(notusedforaprocess) todetectifthepipeisvalidornot. 7. If the the user connects with a name already used, the connection will be closed. 8. Remembertosleepviausleepinallpollingloops! 9. Thislabcanbedonewithstaticmemoryallocation–youdonotneedtoallocateanydynamicmemory. Forthis reason, memset is a handy call to zero out a buffer for repeated use (something you may want to do). 10. You may need to build up strings for message, use (sprintf) for this. 11. To manipulate strings, functions like strcpy, strncpy, strtok, strlen may be handy. But, remember toALLOCATEthe memory for any strings you are creating.
8 Suggestions Some suggestions regarding implementation. 1. Dividing the work among team members: The project could be divided into segments that may be done by different members. One way is to divide it into the following: (a) Writing the server program (creating child processes). (b) Writing the command handlers in the SERVER program. (c) Writing the user program. 2. Recommended steps to get going: (a) Start with writing a SERVER and USER, which prints a prompt, reads any input provided and fills up a string with that input.
5
(b) Write a basic SERVER that waits connections from USERS. Try to get the message passing working between the SERVER and child processes. (c) Write a basic USER that connects to the SERVER and gets two pipe file descriptors to communicate with the server. (d) Get the message passing working between the USER and child process. (e) Implement all commands, putting all of the above pieces together.
9 GradingCriteria 5% README file. Be explicit about your assumptions for the implementation.
20% Documentation with code, Coding and Style. (Indentations, readability of code, use of defined constants rather than numbers, modularity, non-usage of global variables etc.)
75% Test cases
1. Correctness: Your submitted program does the following tasks correctly: (a) Starts the server and get inputs. (b) Demonstrates correct usage of pipes by transferring different kinds of messages as their intended purpose – broadcast as well as peer-to-peer. (c) all exiting is done cleanly. 2. Error handling: (a) Handling invalid user name specification in the commands. (b) Exiting the SERVER should close all the other user sessions. (c) Error code returned by various system/wrapper-library calls. (d) There should be no ”Broken-Pipe” error when your program executes. Also, appropriate cleanup must be done whenever any of the child-processes (SERVER, child, and USER processes) terminates. For eg., closing the pipe ends.
10 Documentation You must include a README file which describes your program. It needs to contain the following: 1. The purpose of your program 2. A brief description of who did what on the lab 3. How to compile the program 4. How to use the program from the shell (syntax) 5. What exactly your program does 6. Any explicit assumptions you have made 7. Your strategies for error handling
6
The README file does not have to be very long, as long as it properly describes the above points. Proper in this case means that a first-time user will be able to answer the above questions without any confusion. Withinyourcodeyoushoulduseoneortwosentencestodescribeeachfunctionthatyouwrite. Youdonotneedto commenteverylineofyourcode. However,youmightwanttocommentportionsofyourcodetoincreasereadability. At the top of your README file and main C source file please include the following comment: /* CSci4061 F2018 Assignment 2 * section: one digit number * date: mm/dd/yy * name: full name1, full name2 (for partner) * id: d for first name, id for second name */
11 Deliverables: 1. Files containing your code 2. A README file (readme and c code should indicate this is assignment 2).
Note: You will need to provide makefile to be used by us to compile your program with the standard make utility. All files should be submitted on the class canvas site. This is your official submission that we will grade. Please note that future submissions under the same homework title OVERWRITE previous submissions; we can only grade the most recent submission. Communicate effectively, work together, share the load, and submit ONE solution All files should be submitted using the SUBMIT utility. You can find a link to it on the class website. This is your official submission that we will grade. We will only grade the most recent and on-time submission