2008年11月29日 星期六

Midterm ex3

Please revise the above program so that the server will convert the IP address of the client and the server to numbers. Note that, the numbers should be shown on the console of the server. (Remember to check the correctness of the numbers.)

/* 修改 ex2 的部分用藍色顯示,位指轉數字要用ntohl() 轉才不會有 byte order 的問題 ( 即 a*128^3+b*128^2+c*128^1+d*128^0 變成 a*128^0+b*128^2+c*128^2+d*128^3 )*/

//-------------------------------------------------------------------------------------------
//tcpcli01.c
#include "unp.h"

void inexp(FILE *fp, int sockfd)
{
 char sendline[MAXLINE], recvline[MAXLINE];

 do {
  printf("Please enter an expression (e.g. 123+456):\n");
  if (Fgets(sendline, MAXLINE, fp) != NULL) {
   Writen(sockfd, sendline, strlen(sendline));
   if (Readline(sockfd, recvline, MAXLINE) == 0)
    err_quit("inexp: server terminated prematurely");
   Fputs(recvline, stdout);
  }
 } while (strlen(recvline)>10);
}

int main(int argc, char **argv)
{
 int sockfd, port;
 struct sockaddr_in servaddr;

 if (argc != 3)
  err_quit("usage: tcpcli ");

 sockfd = Socket(AF_INET, SOCK_STREAM, 0);

 bzero(&servaddr, sizeof(servaddr));
 servaddr.sin_family = AF_INET;
 if (sscanf(argv[2],"%d", &port)==1)
  servaddr.sin_port = htons(port);
 Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);

 Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));

 inexp(stdin, sockfd); /* do it all */

 exit(0);
}
//-------------------------------------------------------------------------------------------


//-------------------------------------------------------------------------------------------
//tcpserv01.c
#include "unp.h"

void retrt(int sockfd)
{
 char buf[MAXLINE], rep[MAXLINE], op;
 int a, b;
 int success=0;

 do
 {
  a=b=0;
  if (read(sockfd, buf, MAXLINE)>0)
  {
   printf("Received expression: %s\n",buf);
   if (sscanf(buf, "%d%c%d",&a, &op, &b)!=3)
    snprintf(rep, sizeof(rep), "Invalid input: %s\n", buf);
   else if (a>=100 && a<=999 && b>=100 && b<=999)
   {
     switch(op)
    {
     case '+': snprintf(rep, sizeof(rep), "%d\n", a+b); success=1;
     break;
     case '-': snprintf(rep, sizeof(rep), "%d\n", a-b); success=1;
     break;
     case '*': snprintf(rep, sizeof(rep), "%d\n", a*b); success=1;
     break;
     case '/': snprintf(rep, sizeof(rep), "%d\n", a/b); success=1;
     break;
     case '%': snprintf(rep, sizeof(rep), "%d\n", a%b); success=1;
     break;
     default: snprintf(rep, sizeof(rep), "Invalid operator: %c\n", op);
    }
   }
   else
    snprintf(rep, sizeof(rep), "Invalid number: %d or %d\n", a, b);
   Writen(sockfd, rep, strlen(rep));
  }
 } while(success==0);
}

int main(int argc, char **argv)
{
 int listenfd, connfd;
 pid_t childpid;
 socklen_t clilen, addrlen;
 struct sockaddr_in cliaddr, servaddr, localaddr, peeraddr;

 listenfd = Socket(AF_INET, SOCK_STREAM, 0);

 bzero(&servaddr, sizeof(servaddr));
 servaddr.sin_family = AF_INET;
 servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
 servaddr.sin_port = htons(0);

 Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));

 bzero(&localaddr, sizeof(localaddr));
 addrlen = sizeof(localaddr);

bzero(&localaddr, sizeof(localaddr));
addrlen = sizeof(localaddr);

 if (getsockname(listenfd, (SA *) &localaddr, &addrlen)==0)
 {
  printf("Server's IP address: %s\n", inet_ntoa(localaddr.sin_addr));
  printf("Server's port number: %d\n\n", ntohs(localaddr.sin_port));
 }

 Listen(listenfd, LISTENQ);
 
 for ( ; ; ) {
  clilen = sizeof(cliaddr);
  connfd = Accept(listenfd, (SA *) NULL, NULL);
  bzero(&localaddr, sizeof(localaddr));
  addrlen = sizeof(localaddr);
  if (getsockname(connfd, (SA *) &localaddr, &addrlen)==0)
  {
   printf("Server's IP address: %s\n", inet_ntoa(localaddr.sin_addr));
   printf("Server's port number: %d\n\n", ntohs(localaddr.sin_port));
   printf("Server's IP number: %d\n\n", ntohl(localaddr.sin_addr.s_addr));
  }

  bzero(&peeraddr, sizeof(peeraddr));
  addrlen = sizeof(peeraddr);
  if (getpeername(connfd, (SA *) &peeraddr, &addrlen)==0)
  {
   printf("Client's IP address: %s\n", inet_ntoa(peeraddr.sin_addr));
   printf("Client's port number: %d\n\n", ntohs(peeraddr.sin_port));
   printf("Server's IP number: %d\n\n", ntohl(localaddr.sin_addr.s_addr));
  }

  if ( (childpid = Fork()) == 0) { /* child process */
   Close(listenfd); /* close listening socket */
   retrt(connfd); /* process the request */
   exit(0);
  }

  Close(connfd);
 }
}
//-------------------------------------------------------------------------------------------

沒有留言: