??
字號:
/*************************************************************
* 用消息隊列實現的進程間通信的例子example2-05.c example2-06.c
************************************************************/
/*****************************************************************************
* 首先服務進程建立一個消息隊列,然后去讀此消息隊列中客戶端發來的消息
(此消息中應該包括客戶端的進程ID和一個文件的路徑名)。
* 讀到消息后,服務器端會按指定的路徑名去讀文件,然后將文件內容再寫回消息隊列。
* 此后,客戶端會來讀取服務進程為它返回的文件內容,然后打印到標準輸出。
*****************************************************************************/
/*****************************************
* 消息隊列實例 服務器端程序example2-05.c
*****************************************/
#include <STDIO.H>
#include <SYS msg.h>
#include <SYS ipc.h>
#include <SYS types.h>
#include <ERRNO.H>
#include <STRING.H>
#define MAXMESGDATA 1000
#define SVMSG_MODE 777
struct mymesg { //定義用戶自己的數據結構
long mesg_len; /* #bytes in mesg_data, can be 0 */
long mesg_type; /* message type, must be > 0 */
char mesg_data[MAXMESGDATA];
};
size_t msg_send(int id, struct mymesg *mptr)
{
return(msgsnd(id, &(mptr->mesg_type), mptr->mesg_len, 0));
}
/* end mesg_send */
size_t mesg_recv(int id, struct mymesg *mptr)
{
ssize_t n;
n = msgrcv(id, &(mptr->mesg_type), MAXMESGDATA, mptr->mesg_type, 0);
mptr->mesg_len = n; /* return #bytes of data */
return(n); /* -1 on error, 0 at EOF, else >0 */
}
int main()
{
int msgid;
FILE *fp;
char *ptr;
pid_t pid;
ssize_t n;
struct mymesg mesg;
msgid = msgget(1234, SVMSG_MODE | IPC_CREAT); /*、以1234為key創建一個消息隊列 */
for( ; ; ) { /*循環從消息隊列中讀取客戶請求 */
mesg.mesg_type = 1;
if ((n = mesg_recv(msgid, &mesg)) == 0) { //判斷消息是否為空
printf("pathname missing");
continue;
}
mesg.mesg_data[n] = '\0'; /*將消息的數據段格式化成以空字符結束的字符串 */ //即在數據末尾添加“\0”作為結束標志。
if ((ptr = strchr(mesg.mesg_data, ' ')) == NULL) {
printf("bogus request: %s", mesg.mesg_data);
continue;
}
*ptr++ = 0;
pid = atol(mesg.mesg_data); /*獲得發送消息的客戶進程的進程號 */
mesg.mesg_type = pid;
if ((fp = fopen(ptr, "r")) == NULL) { /*以只讀方式打開所請求文件 */
snprintf(mesg.mesg_data + n, sizeof(mesg.mesg_data) -n, ":can't open, %s\n", strerror(errno));
mesg.mesg_len = strlen(ptr);
memmove(mesg.mesg_data, ptr, mesg.mesg_len);
msg_send(msgid, &mesg); /*將文件內容寫回消息隊列 */ //即服務器將讀到的客戶端請求的消息返回給客戶端
}
else { /*若文件不存在,則將客戶的請求消息內容再寫回消息隊列 */
while(fgets(mesg.mesg_data, MAXMESGDATA, fp) != NULL) {
mesg.mesg_len = strlen(mesg.mesg_data);
msg_send(msgid, &mesg);
}
fclose(fp);
}
mesg.mesg_len = 0;
msg_send(msgid, &mesg);
}
exit(0);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -