1. 程式人生 > >自定協議實現網路計算器

自定協議實現網路計算器

  這裡我們的自定執行協議和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;
}