80 likes | 91 Views
The CPAM protocol offers a uniform way to access services of distributed megamodules, using distinct primitives like SETUP and EXAMINE. A TCP/IP implementation follows a Client/Server model for seamless interaction. Code snippet illustrates handling client requests.
E N D
CHAIMS CPAM in TCP/IP Cho Chan and Kun Jiang Nov. 30, 1998 CS 446
What is CPAM (Chaims Protocol for Autonomous Megamodules) ? • Protocol for accessing and using the services or methods offered by distributed and herterogenous megamodules in a uniform way. • Nine Primitives: • SETUP • ESTIMATE • INVOKE • SETPARAM • GETPARAM • EXAMINE • EXTRACT • TERMINATE • TERMINATEALL
Our TCP/IP implementation uses Client/Server model • There’s a server process running with each megamodule. • Server accepts requests from Client, maintain necessary states on behalf of the Client and any particular invocation, execute the correct methods provided by the megamodule, and sends back the result for that request to the Client. • Client establishes connection with the Server, sends request and waits for response.
int main(int argc, char *argv[]) { int sockfd, newsockfd, clilen, childpid, nrecv; struct sockaddr_in cli_addr, serv_addr; if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) err_dump("server: can't open stream socket"); bzero((char *) &serv_addr, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = htonl( INADDR_ANY ); serv_addr.sin_port = htons( SERV_TCP_PORT ); if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr) )) err_dump("server: can't bind local address"); listen(sockfd, 5);
for ( ; ; ) { clilen = sizeof(cli_addr); newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &cli_len); if (newsockfd < 0) err_dump("server: accept error"); nrecv = read(sockfd, servbuf, BUFSIZE); if ( (childpid = fork() ) < 0) err_dump ("server: fork error"); else if (childpid == 0) { close(sockfd); doit(newsockfd, buf, nrecv); exit(0); } close(newsockfd); } }
void doit(int newsockfd, char *buf, int nrecv) { /* depending on the message type, process accordingly */ int nwrit; UInt16 msgid; strcpy(msgid, buf, sizeof(UInt16)); switch (msgid) { case kInvoke: InvokeMsg *msgRecv = (InvokeMsg *) buf; invoke(msgRecv, invHand); InvokeRpy *msgToSend = new InvokeRpy; msgToSend->msgid = kInvokeRpy; msgToSend->msgLen = sizeof(msgToSend); msgToSend->callID = invHand++; break; case kExamine: ExamineMsg *msgRecv = (ExamineMsg *) buf; examine(msgRecv); ExamineRpy *msgToSend = new ExamineRpy; msgToSend->msgid = kExamineRpy; msgToSend->msgLen = sizeof(msgToSend); msgToSend->status = examine( msgRecv->callID); break;
case kSetUp: SetUpMsg *msgRecv = (SetUpMsg *) buf; setup(msgRecv); SetUpRpy *msgToSend = new SetUpRpy; msgToSend->msgid = kSetUpRpy; msgToSend->msgLen = sizeof(msgToSend); msgToSend->moduleID = Megamodule_Handle; break; case kEstimate: EstimateMsg *msgRecv = (EstimateMsg *) buf; EstimateRpy *msgToSend = new EstimateRpy; msgToSend->msgid = kEstimateRpy; strcpy(msgToSend->valList, estimate(msgRecv)); msgToSend->msgLen = sizeof(msgToSend); break; case kExtract: ExtractMsg *msgRecv = (ExtractMsg *) buf; ExtractRpy *msgToSend = new ExtractRpy; msgToSend->msgid = kExtractRpy; strcpy(msgToSend->valList, extract(msgRecv)); msgToSend->msgLen = sizeof(msgToSend); break;
case kTerminateAll: TerminateAllMsg *msgRecv = (TerminateAllMsg *) buf; terminateAll(msgRecv); TerminateAllRpy *msgToSend = new TerminateAllRpy; msgToSend->msgid = kTerminateAllRpy; msgToSend->msgLen = sizeof(msgToSend); break; case kSetParam: SetParamMsg *msgRecv = (SetParamMsg *) buf; setParam(msgRecv); SetParamRpy *msgToSend = new SetParamRpy; msgToSend->msgid = kSetParamRpy; msgToSend->msgLen = sizeof(msgToSend); break; case kGetParam: GetParamMsg *msgRecv = (GetParamMsg *) buf; GetParamRpy *msgToSend = new GetParamRpy; msgToSend->msgid = kGetParamRpy; strcpy(msgToSend->paramList, getParam(msgRecv)); msgToSend->msgLen = sizeof(msgToSend); break; } if ( write(newsockfd, msgToSend, size(msgToSend)) < 0) { err_dump("server: write error"); } }