高性能服务器(基于TCP实现基本的加减乘除等运算)

calc.h

#include
#include
#include
#include
#include

typedef enum {QUIT, ADD, SUB, MUL, DIV, MODE}ENUM_CAL_TYPE; //

#define CMD_SIZE 5

typedef struct calcst
{
       int op1;    //操作数1
       int op2;    //操作数2
       ENUM_CAL_TYPE op;  //操作(+,-,*,/...)
}calcst;

socket.h    (封装)

#define TCP 0
#define UDP 1
#define LISTEN_QUEUE_SIZE 5

int start_up(char *ip, short port, int mode)
{
   int sockfd;
   if(mode == TCP) 
   {
     sockfd = socket(AF_INET, SOCK_STREAM, 0);
   }
   else if(mode == UDP)
   {
     sockfd = socket(AF_INET, SOCK_DGRAM, 0);
   }
   else
   {
     printf("mode error,mode must be TCP or UDP!\n ");
     return -1;
   }
   struct sockaddr_in address;
   address.sin_family = AF_INET;
   address.sin_port = htons(port);
   address.sin_addr.s_addr = inet_addr(ip);

   socklen_t len = sizeof(struct sockaddr);

   int yes = 1;
   setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int));  //地址重用
   
   int ret = bind(sockfd, (struct sockaddr*)&address, len);
   if(ret == -1)
   {
     perror("bind");
     return -1;
   }

   if(mode == TCP)
   {
     ret = listen(sockfd, LISTEN_QUEUE_SIZE);
     if(ret == -1)
     {
       perror("listen");
       return -1;
     }
   }

   return sockfd;
}

 

ser.c

#include"socket.h"
#include"calc.h"
int main(int argc, char *argv[])
{
  void process_hander(int sockConn);
  int sockSer = start_up(argv[1], atoi(argv[2]), TCP);
  if(sockSer == -1)
  {
   perror("socket error\n");
   return -1;
  }
  printf("Server waiting connect\n");
  struct sockaddr_in addrCli;
  socklen_t len = sizeof(struct sockaddr);
  int sockConn;
  while(1)
  {
    sockConn = accept(sockSer, (struct sockaddr*)&addrCli, &len);
    if(sockConn == -1)
    { 
      perror("Client connect fail\n");
      return -1;
    }
    else
    {
      printf("<=========Client=============>\n");       //打印客户端信息 IP port
      printf("< ip = %s>\n", inet_ntoa(addrCli.sin_addr)); 
      printf("< port = %d>\n", ntohs(addrCli.sin_port));
    }

    pid_t pid = fork();
    if(pid == 0)
    {
      process_hander(sockConn);   //子进程 --交给处理函数
    }
    else if(pid > 0)
    {
      close(sockConn);            
    }
    else
    {
      perror("fork");
    }
  } 
  close(sockSer);
  return 0;
}
 
 void process_hander(int sockConn)
{
  calcst oper;
  int  ret;
  int result;
  while(1)
  {
    ret = recv(sockConn, &oper, sizeof(oper), 0);
    if(ret < 0)
    {
     perror("receve error");
     continue;
    }
    if(oper.op == ADD)                  
     result = oper.op1 + oper.op2;
    else if(oper.op == SUB)
     result = oper.op1 - oper.op2;
    else if(oper.op == MUL)
     result = oper.op1 * oper.op2;
    else if(oper.op == DIV)
     result = oper.op1 / oper.op2;
    else if(oper.op == MODE)
     result = oper.op1 % oper.op2;
    else if(oper.op == QUIT)
    {
      printf("Client Quit.\n");
      break;
    }
    ret = send(sockConn, &result, sizeof(result), 0);  //将计算结果发给客户端
    if(result < 0)
    {
     perror("send error");
     continue;
    }
  }
  close(sockConn);
}

cli.c

:

#include"calc.h"
int main(int argc, char *argv[])
{
   int sockCli = socket(AF_INET, SOCK_STREAM, 0);
   struct sockaddr_in addrSer;
   addrSer.sin_family = AF_INET;
   addrSer.sin_port = htons(atoi(argv[2]));
   addrSer.sin_addr.s_addr = inet_addr(argv[1]);

   socklen_t len = sizeof(struct sockaddr);

   int ret = connect(sockCli, (struct sockaddr*)&addrSer, len);
   if(ret == -1)
   {
     perror("connect error\n");
     close(sockCli);
     return -1;
   }
   else
    printf("connect server success\n");

   calcst oper;
   char cmd[CMD_SIZE];
   int result;
   while(1)
   {
     printf("Please input cmd\n");
     scanf("%s", cmd);
     printf("Please input op1 and op2\n");
     scanf("%d %d", &oper.op1, &oper.op2);
     if(strcmp(cmd, "add") == 0)
      oper.op = ADD;
     else if(strcmp(cmd, "sub") == 0)
      oper.op = SUB;
     else if(strcmp(cmd, "mul") == 0)
      oper.op = MUL;
     else if(strcmp(cmd, "div") == 0)
      oper.op = DIV;
     else if(strcmp(cmd, "mode") == 0)
      oper.op = MODE;
     else if(strcmp(cmd,"quit") == 0)
      break;
     ret = send(sockCli, &oper, sizeof(oper), 0);   //客户端将要计算的数据和操作发给服务器
     if(ret < 0)
     {
       perror("send data error");
       continue;
     }
     ret = recv(sockCli, &result, sizeof(result), 0);   //接受来自服务器的计算结果
     if(ret < 0)
     {
       perror("receve  error");
       continue;
     }
     printf("result = %d\n", result);
   }
   close(sockCli);
   printf("System Quiting...");
}

运行效果:

高性能服务器(基于TCP实现基本的加减乘除等运算)_第1张图片

当然这里有点小问题,就是客户怎么知道你的cmd 该输入啥, 其实可以打印一个菜单来解决...说白了,这是一个只有你自己才能使用的小型计算器...haha

 

 

 

 

 

 

你可能感兴趣的:(Linux)