1 简介在本案例研究中,您将在消息中实现一个简单的日志服务。 2 规格 该任务分为两部分,一个消息记录服务器和一个用于消息记录的库。 服务器侦听收听消息并绘制日志消息。 提供一种更方便的方式访问消息。 您已经获得了一个程序来测试您的库是否与您的 您需要查看讲义以及第 4 节中提供的文档 来实施这些计划。 2.1 消息记录服务器 日志服务器应该尝试创建消息,如果失败则它...

1 answer below »
1 简介在本案例研究中,您将在消息中实现一个简单的日志服务。 2 规格 该任务分为两部分,一个消息记录服务器和一个用于消息记录的库。 服务器侦听收听消息并绘制日志消息。 提供一种更方便的方式访问消息。 您已经获得了一个程序来测试您的库是否与您的 您需要查看讲义以及第 4 节中提供的文档 来实施这些计划。 2.1 消息记录服务器 日志服务器应该尝试创建消息,如果失败则它 以错误终止,如果应消息实际存在,则不运行 (IPC_EXCL将在这里提供帮助)。 连接到消息,程序应该是一个循环中的目标,接收消息sage,将其打印到stdout 。消息的格式应为: 编号:留言 其中id是消息结构中的类型,message是消息字段。 服务器应在收到SIGINT后彻底关闭(即删除消息)(通过同时按下控制和C键生成)。 示例代码文件logservice.h和logserver.c构成 您这部分的解决方案。此文件中有许多注释可以帮助您制定 你的代码。 2.2 消息库 消息传递库包含两个函数,都在 logservice.h 中定义: int initLogService() 这个函数应该初始化消息队列来记录消息,返回 如果成功则为id ,错误时为-1 。 此函数不应尝试创建消息队列,仅将其附加到 过程。 1 int logMessage(int id, char *message) 此函数将作为字符串消息传递的消息记录到日志中 服务标识。它应该在成功时返回0 ,在错误时返回-1 。 发送消息时,该函数应将进程pid编码为 消息的类型字段,以及消息字段中的字符串。 如果消息太长(即长于 MSGCHARS ),示例行为包括将消息分解为 较小的碎片或简单地拒绝它。无论选择什么,文档中的 头文件应该反映这个选择。 示例代码文件logservice.h和logservice.c应构成 您对此部分的解决方案。 3 示例代码 除了示例代码文件之外,还提供了两个附加文件,一个makefile 包含构建规则和服务器启动脚本。 make实用程序简化了大型项目的构建过程,介绍性文档make 的说明包含在文档部分(第 4 节)中。使用make来自动mate 编译过程只需在终端输入“ make ”(与另一个在同一目录中) fifiles),它将使用makefile中定义的规则来构建日志服务器和 来自源文件的logclient可执行文件,它还将确保 启动 server.sh脚本是可执行的。如果此后没有任何源文件发生更改 最后一次构建(基于它们的时间戳)make实用程序不会重新构建可执行文件。 应该不需要修改makefile ,它的格式有点繁琐,所以更安全 从v UWS 下载文件而不是键入它。 启动 server.sh脚本将在新的 termi 中打开logserver程序最终窗口为您服务。此脚本检测主机操作系统并执行等效的 此检测后的动作。无需了解此文件如何实现其目标。


Practical Case Study C Operating Systems Programming – 300698 1 Introduction In this case study you will implement a simple logging service built on top of amessage queue. 2 Specification The task is broken into two parts, a message logging server, and a library to log messages. The message server listens to a message queue and extracts the log messages from it. The library provides a more convenient way access the message queue. You have been provided with a program to test that your library communicates with your server. You will need to review the lecture notes, and the documentation supplied in Section 5 to implement these programs. 2.1 Message Logging Server The message logging server should attempt to create the message queue, if this fails then it should terminate with an error message, it should not run if the message queue actually exists (IPC_EXCL will help here). Once connected to the message queue, the program should sit in a loop, receiving a mes- sage, and printing it to the stdout. Messages should be formatted: id: message where id is the type from the message structure and message is the message field. The server should shutdown cleanly (i.e. delete the message queue) on receipt of a SIGINT (generated by pressing control and C keys at the same time). The sample code files logservice.h and logserver.c should form the basis of your solution for this part. There are a number of comments in this file to help you structure your code. 2.2 Messaging library The messaging library consists of two functions, both defined in logservice.h: int initLogService() This function should initialise the message queue to log messages to, returning an id if successful, and -1 on error. This function should not attempt to create the message queue, only attach it to the process. 1 int logMessage(int id, char *message) This function logs the message passed as the string message to the log service id. It should return 0 on success and -1 on error. When sending a message, the function should encode the processes pid into the type field of the message, and the string into the message field. It is your choice what to do if the message is too long (i.e. longer than MSGCHARS), sample behaviours include breaking the message up into smaller pieces or simply rejecting it. Whatever the choice, the documentation in the header file should reflect this choice. The sample code files logservice.h and logservice.c should form the basis of your solution for this part. 3 Marking Scheme Refer to the vUWS site for a marking rubric. 2 4 Sample Code In addition to the sample code files, two additional files have been provided, a makefile that contains build rules, and a server launch script. The make utility simplifies the build process for large projects, introductory documen- tation for make is included in the documentation section (Sec. 5). To use make to auto- mate compile process simply type “make” at the terminal (in the same directory as the other files), it will use the rules defined in the makefile to build both the logserver and logclient executables from the source files, and it will also ensure that the launch server.sh script is executable. If none of the source files have changed since the last build (based on their timestamps) the make utility will not rebuild the executables. There should be no need to modify the makefile, its format is a bit fussy so it is safer to download the file from vUWS than type it up. The launch server.sh script will open the logserver program in a new termi- nal window for you. This script detects the host operating system and performs an equivalent action after this detection. There is nop need to understand how this file achieves its goal. 4.1 logservice.h /* logservice.h -- definitions for the log service */ #ifndef LOGSERVICE_H /* prevent multiple inclusion */ #define LOGSERVICE_H #include #include #include #include #include #include #include /* key for the queue */ #define KEY ftok("logservice.h", ’a’) /* message structure */ #define MSGCHARS 255 /* MSGCHARS is the number of characters in the message!*/ struct message { long type; char message[MSGCHARS+1]; /* allow it to be a string! */ }; /* function prototypes */ int logServiceInit(); /* initialises the log service client, returns a service id */ int logMessage(int serviceId, char* message); /* logs the message message to the log service serviceID */ #endif /* ifndef LOGSERVICE_H */ 3 4.2 logservice.c /* logservice.c -- implementation of the log service */ #include "logservice.h" int logServiceInit() { int id; /* TODO: connect to message queue here */ return id; } int logMessage(int serviceId,char *message) { int rv; printf("The message is \"%s\"\n", message); /* TODO: Validate message length here */ /* TODO: Send the message */ return rv; } 4 4.3 logclient.c /* logclient.c -- implements a simple log service client */ #include "logservice.h" int main(int argc,char **argv) { int id; /* Check if arguments are present on command line */ if (arg < 2)="" {="" fprintf(stderr,="" "usage:="" %s="" message",="" argv[0]);="" exit(1);="" }="" *="" connect="" to="" the="" log="" service="" */="" if(-1="=" (id="logServiceInit()))" {="" perror("connecting="" to="" queue");="" exit(1);="" }="" *="" log="" the="" message="" supplied="" on="" the="" command="" line="" */="" if(-1="=" logmessage(id,="" argv[1]))="" {="" perror("sending="" message");="" exit(1);="" }="" return="" 0;="" }="" 5="" 4.4="" logserver.c="" *="" logserver.c="" --="" implementation="" of="" the="" log="" server="" */="" #include=""> #include "logservice.h" int queue_id; /* stores queue_id for use in signal handler */ void handler(int sig); int main() { printf("Please make me useful!\n"); exit(0); /* delete this line once you start */ /* TODO: initialise the message queue here */ /* install signal handler to clean up queue * do this after you have created the queue * then you dont need to check if it is valid! */ signal(SIGINT, handler) while (1) { /* TODO: receive a message */ /* TODO: display the message */ } return 0; } void handler(int sig) { /* TODO: clean up the queue here */ exit(0); } 6 4.5 makefile # makefile -- rules to build OSP workshop C # to use simply type "make" # this will build the server and client and launcher script # note, this is a configuration file for the MAKE utility # do not try to run it directly # if typing up the file, the indented lines need to be indented # with TABS not spaces. all: logserver logclient chmod +x launch_server.sh clean: rm -f *.o logserver logclient logclient: logclient.o logservice.o logservice.o: logservice.c logservice.h logserver: logserver.o logserver.o: logserver.c logservice.h 4.6 launch server.sh #!/bin/bash ### This script launches the logserver process in a new window. ### Magic is needed for OSX as I can’t rely on xterm being installed! ### Only works when logged in via the console, not Putty/SSH ### It is not necessary to understand this script! if [ $(uname) == "Darwin" ] then osascript -e ’tell application "Terminal" to do script "cd ’$PWD’; \ ./logserver; exit; "’ else xterm -title "Log Server" -e ’./logserver; \ echo press enter to exit; read junk;’ & fi 7 5 Supplementary Materials The material on the following pages is an extract of the linux system documentation and may prove useful in implementing this Workshop. These manual pages are taken from the Linux man-pages Project available at: http://www.kernel.org/doc/man-pages/. 8 http://www.kernel.org/doc/man-pages/ SVIPC(7) Linux Programmer’s Manual SVIPC(7) NAME svipc − System V interprocess communication mechanisms SYNOPSIS # include # include # include # include # include DESCRIPTION This manual page refers to the Linux implementation of the System V interprocess communication mecha- nisms: message queues, semaphore sets, and shared memory segments. In the following, the word resource means an instantiation of one among such mechanisms. Resource Access Permissions For each resource, the system uses a common structure of type struct ipc_perm to store information needed in determining permissions to perform an ipc operation. The ipc_perm structure, defined by the system header file, includes the following members: ushort cuid; /* creator user ID */ ushort cgid; /* creator group ID */ ushort uid; /* owner user ID */ ushort gid; /* owner group ID */ ushort mode; /* r/w permissions */ The mode member of the ipc_perm structure defines, with its lower 9 bits, the access permissions to the resource for a process executing an ipc system call. The permissions are interpreted as follows: 0400 Read by user. 0200 Write by user. 0040 Read by group. 0020 Write by group. 0004 Read by others. 0002 Write by others. Bits 0100, 0010, and 0001 (the execute bits) are unused by the system. Furthermore, "write" effectively means "alter" for a semaphore set. The same system header file also defines the following symbolic constants: IPC_CREAT Create entry if key doesn’t exist. IPC_EXCL Fail if key exists. IPC_NOWAIT Error if request must wait. IPC_PRIVATE Private key. IPC_RMID Remove resource. IPC_SET Set resource options. IPC_STAT Get resource options. Note that IPC_PRIVATE is a key_t type, while all the other symbolic constants are flag fields and can be OR’ed into an int type variable. Message Queues A message queue is uniquely identified by a positive integer (its msqid) and has an associated data structure of type struct msqid_ds, defined in , containing the following members: Linux 0.99.13 1993-11-01 1 SVIPC(7) Linux Programmer’s Manual SVIPC(7) struct ipc_perm msg_perm; ushort msg_qnum; /* no of messages on queue */ ushort msg_qbytes; /* bytes max on a queue */ ushort msg_lspid; /* PID of last msgsnd() call */ ushort msg_lrpid; /* PID of last msgrcv() call */ time_t msg_stime; /* last msgsnd() time */ time_t msg_rtime; /* last msgrcv() time */ time_t msg_ctime; /* last change time */ msg_perm ipc_perm structure that specifies the access permissions on the message queue. msg_qnum Number of messages currently on the message queue. msg_qbytes Maximum number of bytes of message text allowed on the message queue. msg_lspid ID of the process that performed the last msgsnd() system call. msg_lrpid ID of the process that performed the last msgrcv() system call. msg_stime Time of the last msgsnd() system call. msg_rtime Time of the last msgcv() system call. msg_ctime Time of the last system call that changed a member of the msqid_ds structure. Semaphore Sets A semaphore set is uniquely identified by a positive integer (its semid) and has an associated data structure of type struct semid_ds, defined in , containing the following members: struct ipc_perm sem_perm; time_t sem_otime; /* last operation time */ time_t sem_ctime; /* last change time */ ushort sem_nsems; /* count of sems in set */ sem_perm ipc_perm structure that specifies the access permissions on the semaphore set. sem_otime Time of last semop() system call. sem_ctime Time of last semctl() system call that changed a member of the above structure or of one semaphore belonging to the set. sem_nsems Number of semaphores in the set. Each semaphore
Answered 1 days AfterMay 05, 2022

Answer To: 1 简介在本案例研究中,您将在消息中实现一个简单的日志服务。 2 规格 该任务分为两部分,一个消息记录服务器和一个用于消息记录的库。 服务器侦听收听消息并绘制日志消息。 提供一种更方便的方式访问消息。...

Shashi Kant answered on May 06 2022
93 Votes
SOLUTION.PDF

Answer To This Question Is Available To Download

Related Questions & Answers

More Questions »

Submit New Assignment

Copy and Paste Your Assignment Here