2008年11月29日 星期六

HW08

/* Goal : Please design a simple calculator client and server, such that client sends an expression (e.g."123+456"), which contains two operands and an operator, to the server. After received the expression, the server replies the calculating result to the client. Note that, the operands are 3-digit integer, the operator is in {+,-,*,/,%}, the expression is inputted from the keyboard, and the calculating result should be shown on the console of the client. */
//---------------------------------------------------------------------------------------------
//Input : Stdin
//Output : Stdout
//Note : 使用 UDP 協定 , 修改部分用藍色表示
//---------------------------------------------------------------------------------------------
// dg_cli is in udpcli01.c
// dg_echo is in udpserv01.c

#include "unp.h"

void dg_cli(FILE *fp, int sockfd, const SA *pservaddr, socklen_t servlen)
{
 int n;
 char sendline[MAXLINE], recvline[MAXLINE + 1];

 socklen_t len;
 struct sockaddr *preply_addr;

 preply_addr=malloc(servlen);

 while (Fgets(sendline, MAXLINE, fp) != NULL)
 {
  Sendto(sockfd, sendline, strlen(sendline), 0, pservaddr, servlen);

  len=servlen;

  n = Recvfrom(sockfd, recvline, MAXLINE, 0, preply_addr, &len);

  printf("reply from %s (ignore)\n",Sock_ntop(preply_addr,len));

  recvline[n] = 0; /* null terminate */
  Fputs(recvline, stdout);
 }
}

void dg_echo(int sockfd, SA *pcliaddr, socklen_t clilen)
{
 long arg1,arg3;
 char arg2;

 int n;
 socklen_t len;
 char mesg[MAXLINE];

 for ( ; ; )
 {  
  len = clilen;
  n = Recvfrom(sockfd, mesg, MAXLINE, 0, pcliaddr, &len);

  if(sscanf(mesg,"%ld%c%ld",&arg1,&arg2,&arg3)==3)
   if(arg1<100||arg1>999||arg3<100||arg3>999)
    snprintf(mesg,sizeof(mesg),"%s\n","invalid operand");
   else
    switch(arg2)
    {
     case '+':
      snprintf(mesg,sizeof(mesg),"%ld\n",arg1+arg3);
      break;
     case '*':
      snprintf(mesg,sizeof(mesg),"%ld\n",arg1*arg3);
      break;
     case '-':    
      snprintf(mesg,sizeof(mesg),"%ld\n",arg1-arg3);
      break;
     case '/':
      snprintf(mesg,sizeof(mesg),"%ld\n",arg1/arg3);
      break;
     case '%':
      snprintf(mesg,sizeof(mesg),"%ld\n",arg1%arg3);
      break;
     default:
      snprintf(mesg,sizeof(mesg),"%s\n","invalid operantor");
      break;
    }

  Sendto(sockfd, mesg, sizeof(mesg), 0, pcliaddr, len);
 }
}

沒有留言: