自定协议实现网络计算器

  这里我们的自定执行协议和TCP、UDP、IP这些协议不同,我们自定制的协议是应用层的协议。是我们这两个应用所应用的一种特殊传输和接受数据的方式,这里我们是通过结构体来存储数据的,也可以定义一个字符串,当我们的数据发送过去之后,只有我对应的服务端或者客户端明白我这里是在干什么,如何把这一大块数据进行划分。

//这是一个通过自定制协议来实现的网络计算器
//客户端传输过来的数据是提前协定好的
//服务端进行解析之后得到结果返回客户端
//1.创建socket  socket
//2.绑定地址  bind
//3.开始监听  listen
//4.接受收客户端链接  accept
//5.接受客户端的数据
//6.以指定的协议来对数据进行解析
//7.进行计算
//8.返回结果
//9.关闭socket


#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<errno.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
//我们自己设定协议格式
//前四个自己是一个数字
//之后四个字节是另一个数字
//最后一个字节是运算符

typedef struct _cal_req_t
{
    int x;
    int y;
     unsigned char sym;
}cal_req_t;

int main(int argc,char* argv[])
{
    if(argc!=3)
    {
        printf("please input ip/port\n");
        return -1;
    }
    struct sockaddr_in lst_addr;
    struct sockaddr_in cli_addr;
    int lst_fd=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if(lst_fd<0)
    {
        perror("socket error\n");
        return -1;
    }
    lst_addr.sin_family=AF_INET;
    lst_addr.sin_port=htons(atoi(argv[2]));
    lst_addr.sin_addr.s_addr=inet_addr(argv[1]);
    socklen_t len=sizeof(struct sockaddr_in);
    int ret=bind(lst_fd,(struct sockaddr*)&lst_addr,len);
    if(ret<0)
    {
        perror("bind error\n");
        return -1;
    }
    if(listen(lst_fd,5)<0)
    {
        perror("listen error\n");
        return -1;
    }
    while(1)
    {
        int new_fd=accept(lst_fd,(struct sockaddr*)&cli_addr,&len);
        if(new_fd<0)
        {
            perror("accept error\n");
            continue;
        }
        //接受我们特定格式的数据然后开始解析
        cal_req_t req;
        char buff[1024]={0};
        ssize_t rlen=recv(new_fd,(void*)&req,1024,0);
        if(rlen<0)
        {
            perror("recv error\n");
            close(new_fd);
            continue;
        }else if(rlen==0)
        {
            printf("shutdown\n");
            close(new_fd);
        } 
        int sum=0;
        if(req.sym=='+')
        {
            sum=req.x+req.y;
        }
        if(req.sym=='-')
        {
            sum=req.x-req.y;
        }
        if(req.sym=='*')
        {
            sum=req.x*req.y;
        }
        if(req.sym=='/')
        {
            sum=req.x/req.y;
        }
        send(new_fd,(void*)&sum,4,0);
        close(new_fd);
    }
    return 0;
}

 

//这是网络计算器的客户端我们给服务端两个数据一个操作符
//之后接受服务端返回给我们数据并且输出

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<errno.h>
#include<netinet/in.h>
#include<sys/socket.h>
#include<arpa/inet.h>

typedef struct cal_req_t
{
    int x;
    int y;
    unsigned char sym;
}cal_req_t;

int main(int argc,char* argv[])
{ 
   if(argc!=3)
   {
       printf("please input ip/port\n");
       return -1;
   }
   int sockfd=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
   if(sockfd<0)
   {
       perror("socket error\n");
       return -1;
   }
   struct sockaddr_in addr;
   addr.sin_family=AF_INET;
   addr.sin_port=htons(atoi(argv[2]));
   addr.sin_addr.s_addr=inet_addr(argv[1]);
    socklen_t len=sizeof(struct sockaddr_in);
    int ret=connect(sockfd,(struct sockaddr*)&addr,len);
    if(ret<0)
    {
        perror("connect error\n");
        return -1;
    }
    struct cal_req_t req;
    printf("请输入第一个数字\n");
    scanf("%d",&req.x);
    printf("请输入第二个数字\n");
    scanf("%d",&req.y);
    printf("请输入运算符\n");
    scanf("%s",&req.sym);
    send(sockfd,(void*)&req,sizeof(req),0);
    int sum=0;
    recv(sockfd,(void*)&sum,4,0);
    printf("%d%c%d=%d\n",req.x,req.sym,req.y,sum);
    close(sockfd);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值