客戶機(jī)服務(wù)器接收和發(fā)送數(shù)據(jù)的方法
數(shù)據(jù)的傳送過(guò)程
硬件劃分:
├←─── 服務(wù)器 ───→┼← 網(wǎng)絡(luò) →┼←── 客戶機(jī) ──→┤
┌──┐⑥┌──┐⑦┌──┐
┌→┤qid4├→┤ L2 ├→┤qid2├─┐
⑤│ └──┘ └──┘ └──┘ ↓⑧
┌──┐ ┌──┴──┐ ┌──→ ┌──┴──┐ ┌────┐
│ DB ├←→┤s_process │ │ │c_process ├←→┤終端用戶│
└──┘ └──┬──┘ └─── └──┬──┘ └────┘
④↑ ┌──┐ ┌──┐ ┌──┐ │①
└─┤qid3├←┤ L1 ├←┤qid1├←┘
軟件劃分: └──┘③└──┘②└──┘
├←─ s_process ──→┼←tcp_s→┼←tcp_c→┼← c_process →┤
圖2 數(shù)據(jù)在客戶機(jī)服務(wù)器之間傳遞的全過(guò)程
其中s_process和c_process是分別運(yùn)行在服務(wù)器上的服務(wù)器業(yè)務(wù)程序和運(yùn)行在客戶機(jī)上的客戶業(yè)務(wù)進(jìn)程。qid3,qid4和qid1,qid2是分別存在于服務(wù)器及客戶機(jī)上的消息隊(duì)列。
tcp_s和tcp_c是分別運(yùn)行在服務(wù)器和客戶機(jī)上的通信軟件。在客戶機(jī)和服務(wù)器之間建立的兩條連接是L1和L2,其中L1專用于客戶機(jī)至服務(wù)器,L2專用于服務(wù)器至客戶機(jī)。
下面敘述圖2中所示的數(shù)據(jù)傳遞過(guò)程,同時(shí)介紹用于數(shù)據(jù)接收和發(fā)送的四個(gè)函數(shù)。因?yàn)闃I(yè)務(wù)程序不知何時(shí)可以接收或發(fā)送消息,所以這四個(gè)函數(shù)都存在一個(gè)循環(huán)不斷地試圖接收或發(fā)送數(shù)據(jù)。表示消息的數(shù)據(jù)結(jié)構(gòu)是sg_buf,消息由消息類別mtype及正文段mdata組成。
正文段中存放的數(shù)據(jù)是無(wú)結(jié)構(gòu)的,必須定義一種數(shù)據(jù)結(jié)構(gòu)(struct),用結(jié)構(gòu)中的各變量對(duì)mdata進(jìn)行劃分,從而使mdata中的數(shù)據(jù)可以被理解和使用。還可將mdata前面的一部分區(qū)域劃出來(lái)重新命名用作其他用途。消息在整個(gè)數(shù)據(jù)傳遞的過(guò)程中起類似“載體”的作用。 來(lái)源:www.examda.com
#define MSGSIZE 200
struct msg_buf{
long mtype; /* 消息類別 */
long cpid; /* 客戶業(yè)務(wù)進(jìn)程標(biāo)識(shí)號(hào) */
long sid; /* 共享內(nèi)存記錄編號(hào) */
long msgid; /* 消息編號(hào) */
char mdata[MSGSIZE-16]; /* 數(shù)據(jù)區(qū) */
}
① 客戶業(yè)務(wù)程序c_process從終端用戶接收數(shù)據(jù),先存放在一個(gè)結(jié)構(gòu)中,然后將該結(jié)構(gòu)的內(nèi)容依照一定的格式拷入buf->mdata中,然后將buf以消息的形式放入消息隊(duì)列qid1中。
pidc=getpid();/* c_process的進(jìn)程號(hào) */
buf->mtype=1; /* 消息類別都為1 */
buf->sid=0; /* sid在客戶機(jī)沒(méi)用 */
buf->msgid=++msgid;
buf->cpid=pidc;
msgsnd(qid1,buf,MSGSIZE,0);
② 進(jìn)程tcp_c調(diào)用函數(shù)Client_Send從qid1中取得消息,然后往L1寫(xiě)給服務(wù)器。從qid1中取消息時(shí)對(duì)消息并不予于區(qū)別,凡在qid1中的消息都要由進(jìn)程tcp_c來(lái)發(fā)送。
for(;;){ /* 取mtype=1的消息 */
msgrcv(qid1,buf,MSGSIZE,1,0);
write(s_w,buf,i+1);
}
數(shù)據(jù)的傳送過(guò)程
硬件劃分:
├←─── 服務(wù)器 ───→┼← 網(wǎng)絡(luò) →┼←── 客戶機(jī) ──→┤
┌──┐⑥┌──┐⑦┌──┐
┌→┤qid4├→┤ L2 ├→┤qid2├─┐
⑤│ └──┘ └──┘ └──┘ ↓⑧
┌──┐ ┌──┴──┐ ┌──→ ┌──┴──┐ ┌────┐
│ DB ├←→┤s_process │ │ │c_process ├←→┤終端用戶│
└──┘ └──┬──┘ └─── └──┬──┘ └────┘
④↑ ┌──┐ ┌──┐ ┌──┐ │①
└─┤qid3├←┤ L1 ├←┤qid1├←┘
軟件劃分: └──┘③└──┘②└──┘
├←─ s_process ──→┼←tcp_s→┼←tcp_c→┼← c_process →┤
圖2 數(shù)據(jù)在客戶機(jī)服務(wù)器之間傳遞的全過(guò)程
其中s_process和c_process是分別運(yùn)行在服務(wù)器上的服務(wù)器業(yè)務(wù)程序和運(yùn)行在客戶機(jī)上的客戶業(yè)務(wù)進(jìn)程。qid3,qid4和qid1,qid2是分別存在于服務(wù)器及客戶機(jī)上的消息隊(duì)列。
tcp_s和tcp_c是分別運(yùn)行在服務(wù)器和客戶機(jī)上的通信軟件。在客戶機(jī)和服務(wù)器之間建立的兩條連接是L1和L2,其中L1專用于客戶機(jī)至服務(wù)器,L2專用于服務(wù)器至客戶機(jī)。
下面敘述圖2中所示的數(shù)據(jù)傳遞過(guò)程,同時(shí)介紹用于數(shù)據(jù)接收和發(fā)送的四個(gè)函數(shù)。因?yàn)闃I(yè)務(wù)程序不知何時(shí)可以接收或發(fā)送消息,所以這四個(gè)函數(shù)都存在一個(gè)循環(huán)不斷地試圖接收或發(fā)送數(shù)據(jù)。表示消息的數(shù)據(jù)結(jié)構(gòu)是sg_buf,消息由消息類別mtype及正文段mdata組成。
正文段中存放的數(shù)據(jù)是無(wú)結(jié)構(gòu)的,必須定義一種數(shù)據(jù)結(jié)構(gòu)(struct),用結(jié)構(gòu)中的各變量對(duì)mdata進(jìn)行劃分,從而使mdata中的數(shù)據(jù)可以被理解和使用。還可將mdata前面的一部分區(qū)域劃出來(lái)重新命名用作其他用途。消息在整個(gè)數(shù)據(jù)傳遞的過(guò)程中起類似“載體”的作用。 來(lái)源:www.examda.com
#define MSGSIZE 200
struct msg_buf{
long mtype; /* 消息類別 */
long cpid; /* 客戶業(yè)務(wù)進(jìn)程標(biāo)識(shí)號(hào) */
long sid; /* 共享內(nèi)存記錄編號(hào) */
long msgid; /* 消息編號(hào) */
char mdata[MSGSIZE-16]; /* 數(shù)據(jù)區(qū) */
}
① 客戶業(yè)務(wù)程序c_process從終端用戶接收數(shù)據(jù),先存放在一個(gè)結(jié)構(gòu)中,然后將該結(jié)構(gòu)的內(nèi)容依照一定的格式拷入buf->mdata中,然后將buf以消息的形式放入消息隊(duì)列qid1中。
pidc=getpid();/* c_process的進(jìn)程號(hào) */
buf->mtype=1; /* 消息類別都為1 */
buf->sid=0; /* sid在客戶機(jī)沒(méi)用 */
buf->msgid=++msgid;
buf->cpid=pidc;
msgsnd(qid1,buf,MSGSIZE,0);
② 進(jìn)程tcp_c調(diào)用函數(shù)Client_Send從qid1中取得消息,然后往L1寫(xiě)給服務(wù)器。從qid1中取消息時(shí)對(duì)消息并不予于區(qū)別,凡在qid1中的消息都要由進(jìn)程tcp_c來(lái)發(fā)送。
for(;;){ /* 取mtype=1的消息 */
msgrcv(qid1,buf,MSGSIZE,1,0);
write(s_w,buf,i+1);
}