当前位置:   article > 正文

Linux——实现一个简单的网络版计算器_基于linux的计算器编写

基于linux的计算器编写

1.程序简介

  • 我们想要实现一个服务器版的简易计算器,我们需要从客户端发送两个数据以及所要操作的类型,然后由服务器进行处理,并将结果返回至客户端

2.思路

  • 这种运算的规则,我们也可以认为是一种协议,因为是客户端与服务端达成的某种约定
  • 我们需要定义两个结构体去表示客户端与服务端之间进行交互的信息
  • 发送数据时将这个结构体按照一个规则转换成字符串,接收数据的时候再按照相同的规则把字符串转化为结构体
  • 这个过程就叫做序列化反序列化

3.代码实现

  • Makfile
FlAG =-std=c++11 -lpthread

.PHONY:all	
all:Client Server

Client:Client.cc
	g++ -o $@ $^ $(FLAG) static 
Server:Server.cc
	g++ -o $@ $^ $(FLAG) -g  

.PHONY:clean
clean:
	rm -f Client Server
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • Client.cc
#ifndef __CLIENT_HPP__
#define __CLIENT_HPP__


#include<iostream>
#include<string>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<arpa/inet.h>
#include<sys/wait.h>
#include"Protocol.hpp"
using namespace std;
class client
{
  private:
    int port;
    int sock;
    string ip;
  public:
    client(string _ip, int _p)
      :ip(_ip)
      ,port(_p)
      ,sock(-1)
    {}

    void initClient()
    {
      sock = socket(AF_INET, SOCK_STREAM, 0);
      if(sock < 0)
      {
        cerr << "socket error" << endl;
        exit(2);
      }
    }

    void cal(int sock)
    {
      //短链接来完成对应的计算 就是A发一个请求 B处理一个 B申请断开连接 
      request_t rq;
      response_t rsp = {4,0};//默认从4开始
      ssize_t s = recv(sock, &rq, sizeof(rq), 0);//有BUG
      if(s > 0)
      {
        switch(rq.op)
        {
          case '+':
            rsp.result = rq.x + rq.y;
            break;
          case '-':
            rsp.result = rq.x - rq.y;
            break;
          case '*':
            rsp.result = rq.x * rq.y;
            break;
          case '/':
            if(rq.y != 0)
            {
              rsp.result = rq.x / rq.y;
            }
            else 
            {
              rsp.code = 2;
            }
            break;
          case '%':
            if(rq.y != 0)
            {
              rsp.result = rq.x % rq.y;
            }
            else 
            {
              rsp.code = 2; 
            }
            break;
          default:
            //走到这里说明 操作符不对
            rsp.code = 3;
            break;
        }
      }
      send(sock, &rsp, sizeof(rsp), 0);
      close(sock);

    }

    void start()
    {
      struct sockaddr_in server;
      server.sin_family = AF_INET;
      server.sin_port = htons(port);
      server.sin_addr.s_addr = inet_addr(ip.c_str());

      if(connect(sock ,(struct sockaddr*)&server, sizeof(server)) <  0)
      {
        cerr << "connect error!\n" << endl;
        exit(2);
      }

      request_t rq;
      response_t rsp;
      cout << "data1# ";
      cin >> rq.x;
      cout << "data2# ";
      cin >> rq.y;
      cout << "op#";
      cin >> rq.op;

      send(sock,&rq,sizeof(rq),0);
      recv(sock,&rsp,sizeof(rsp),0);

      cout << "code : " << rsp.code << endl;
      cout << "rersult : " << rsp.result << endl;
    }
    ~client()
    {
      close(sock);
    }
};

#endif 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • Client.cc
#include "Client.hpp"


void Menu(string proc)
{
  cout << " usage : \n\t";
  cout << proc << "svr_ip svr_port" << endl;
}
int main(int argc, char *argv[])
{
  if(argc != 3)
  {
    Menu(argv[0]);
    exit(1);
  }

  client *cp = new client(argv[1],atoi(argv[2]));
  cp->initClient();
  cp->start();

  return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • Server.hpp
#ifndef __SERVER_HPP__
#define __SERVER_HPP__


#include<iostream>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<arpa/inet.h>
#include<arpa/inet.h>
#include<sys/wait.h>
#include"Protocol.hpp"
using namespace std;
class server
{
  private:
    int port;
    int lsock;
  public:
    server(int _p):port(_p)
    {}

    void initServer()
    {
      lsock = socket(AF_INET, SOCK_STREAM, 0);
      if(lsock < 0)
      {
        cerr << "socket error" << endl;
        exit(2);
      }
      struct sockaddr_in local;
      local.sin_family = AF_INET;
      local.sin_port = htons(port);
      local.sin_addr.s_addr = INADDR_ANY;
      //开始绑定
      if(bind(lsock, (struct sockaddr*)&local, sizeof(local)) < 0)
      {
        cerr << "bind error !" << endl;
        exit(3);
      }
      if(listen(lsock, 5) < 0)
      {
        cerr << "listen error!\n" << endl;
      }
    }

    void cal(int sock)
    {
      //短链接来完成对应的计算 就是A发一个请求 B处理一个 B申请断开连接 
      request_t rq;
      response_t rsp = {4,0};//默认从4开始
      ssize_t s = recv(sock, &rq, sizeof(rq), 0);//有BUG
      if(s > 0)
      {
        switch(rq.op)
        {
          case '+':
            rsp.result = rq.x + rq.y;
            break;
          case '-':
            rsp.result = rq.x - rq.y;
            break;
          case '*':
            rsp.result = rq.x * rq.y;
            break;
          case '/':
            if(rq.y != 0)
            {
              rsp.result = rq.x / rq.y;
            }
            else 
            {
              rsp.code = 2;
            }
            break;
          case '%':
            if(rq.y != 0)
            {
              rsp.result = rq.x % rq.y;
            }
            else 
            {
              rsp.code = 2; 
            }
            break;
          default:
            //走到这里说明 操作符不对
            rsp.code = 3;
            break;
        }
      }
      send(sock, &rsp, sizeof(rsp), 0);
      close(sock);

    }

    void start()
    {
      struct sockaddr_in peer;
      for(;;)
      {
        socklen_t len = sizeof(peer);
        int sock = accept(lsock, (struct sockaddr*)&peer,&len);
        if(sock < 0)
        {
          cerr << "accept error!\n" << endl;
          continue;
        }
        if(fork() == 0)
        {
          if(fork() > 0)
          {
            exit(0);
          }
          //孙子
          close(lsock);
          //todo
          cal(sock);
          exit(0);
        }
        close(lsock);
        waitpid(-1,nullptr,0);
      }
    }
    ~server()
    {
      close(lsock);
    }
};

#endif 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • Server.cc
#include "Server.hpp"


void Menu(string proc)
{
  cout << " usage : \n\t";
  cout << proc << "port" << endl;
}
int main(int argc, char *argv[])
{
  if(argc != 2)
  {
    Menu(argv[0]);
    exit(1);
  }

  server *sp = new server(atoi(argv[1]));
  sp->initServer();
  sp->start();

  return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • Protocol.hpp
#ifndef __PROTOCOL_HPP__
#define __PROTOCOL_HPP__  

#include<iostream>

typedef struct request
{
  int x;
  int y;
  char op;//操作符
}request_t;

typedef struct response
{
  int code;//状态码 对应不同的错误情况
  int result;
}response_t;

#endif  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

4.运行结果

在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/黑客灵魂/article/detail/978201?site
推荐阅读
相关标签
  

闽ICP备14008679号