网络通信实现一个加法器

一、简单的加法器:实现客户端发送数据,服务器端计算出结果后返还给客户端
proto.h
# pragma once
//以下的两个结构体就是我们此处自定制的应用层协议
//客户端给服务器端发送的结构体
typedef struct Request{
   int a;
   int b;
}Request;
//服务器端给客户端相应的结构体
typedef struct Response{
   int sum;
}Response;
server.c
# include<unistd.h>
# include<stdlib.h>
# include<sys/socket.h>
# include<netinet/in.h>
# include<arpa/inet.H>
# include"simpleproto.h"
typedef struct sockaddr sockaddr;
typedef struct sockaddr_in sockaddr_in;
int main(int argc,char *argv[]){
    if(argc!=3){
       printf("Usage ./server[ip][port]\n");
       return 1;
    }
    int fd=socket(AF_INET,SOCK_DGRAM,0);
    if(fd<0){
       perror("socket");
       return 1;
    }
    sockaddr_in addr;
    addr.sin_family=AF_INET;
    addr.sin_addr.s_addr=inet_addr(argv[1]);
    addr.sin_port=htons(atoi(argv[2]));
    int ret=bind(fd,(sockaddr*)&addr,sizeof(addr));
    if(ret<0){
      perror("bind");
      return 1;
    }
    while(1){
      sockaddr_in peer;
      socklen_t len=sizeof(peer);
//buf中按理要包含两个数字,那么这个buf的结构应该式啥样的?
//比如:要求字符串中两个数字之间用‘+’分割
//协议1:10+20
//协议2:10,20
//协议3:构造一个结构体,结构体中包含两个整数。
      char buf[1024]={0};
      Request req;
      ssize_t read_size=recvfrom(fd,&req,sizeof(req),0,(sockaddr*)&peer,&pen);
      if(read_size<0){
         perror("recvfrom");
         continue;
      }
//一下的代码,相当于针对读取到的请求内容,进行处理和计算
      int sum=req.a+req.b;
      Response resp;
      resp.sum=sum;
      sendto(fd,&resp,sizeof(resp),0,(sockaddr*)&peer,len);
   }
   return 0;
}
client.c
# include<unistd.h>
# include<stdlib.h>
# include<sys/socket.h>
# include<netinet/in.h>
# include<arpa/inet.H>
# include"simpleproto.h"
typedef struct sockaddr sockaddr;
typedef struct sockaddr_in sockaddr_in;
int main(int argc,char *argv[]){
    if(argc!=3){
       printf("Usage ./server[ip][port]\n");
       return 1;
    }
    int fd=socket(AF_INET,SOCK_DGRAM,0);
    if(fd<0){
       perror("socket");
       return 1;
    }
    sockaddr_in server_addr;
    server_addr.sin_family=AF_INET;
    server_addr.sin_addr.s_addr=inet_addr(argv[1]);
    server_addr.sin_port=htons(atoi(argv[2]));
//从标准输入中读入两个加数
    printf("please input the first number:");
    int a=0;
    scanf("%d",&a);
    printf("please input the second number:");
    int b=0;
    scanf("%d",&b);
//构造Request结构
    Request req;
    req.a=a;
    req.b=b;
//把Request结构体发送到服务器上
    sendto(fd,&req,sizeof(req),0,(sockaddr*)&server_addr,sizeof(server_addr));
//尝试读取服务器的返回信息
    Reponse resp;
    recvfrom(fd,&resp,sizeof(resp),0,NULL,NULL);
    printf("sun=%d\n",resp.sum);
    return 0;
}
    
二、实现加减乘除运算(客户端将操作数发送给服务器端,服务器端计算出结果后返回给客户端)
proto.h
//以下的两个结构体就是我们此处自定制的应用层协议
//客户端给服务器端发送的结构体
#pragma once
# define MaxSize 10000
typedef struct Request{
   int *a;
//   int a[MaxSize];
   size_t size;
   //char op;//'+'/'-'/'*'/'\'
   int op;
}Request;
//服务器端给客户端响应的结构体
typedef struct Response{
   int sum;
}Response;
server.c
同简单的加法运算
client.c
# include"proto.h"
# include<unistd.h>
# include<stdlib.h>
# include<sys/socket.h>
# include<netinet/in.h>
# include<arpa/inet.H>
# include"simpleproto.h"
typedef struct sockaddr sockaddr;
typedef struct sockaddr_in sockaddr_in;
int main(int argc,char *argv[]){
    if(argc!=3){
       printf("Usage ./server[ip][port]\n");
       return 1;
    }
    int fd=socket(AF_INET,SOCK_DGRAM,0);
    if(fd<0){
       perror("socket");
       return 1;
    }
    sockaddr_in server_addr;
    server_addr.sin_family=AF_INET;
    server_addr.sin_addr.s_addr=inet_addr(argv[1]);
    server_addr.sin_port=htons(atoi(argv[2]));
    printf("please input the first number:");
    int a=0;
    scanf("%d",&a);
    printf("please input the second number:");
    int b=0;
    scanf("%d",&b);
//构造Request结构体
    Request req;
    req.size=10;
    req.a=(int*)malloc(sizeof(int)*req.size);
//此时,我们要发送的数据并不在Request变量之中,而是需要先把Request对象转换成一个字符串,再发送字符串
//把对象转换成字符串的过程称之为序列化
//把字符串反向的解析为对象的过程,称之为反序列化
    char buf[1024]={0};
    size_t offset=0;
    size_t i=0;
    for(;i<req.size;++i){
       offset+=sprintf(buf+offset,"%d",req.a[i]);
    }
//常用的序列化、反序列化方式
//http协议(包括不限于序列化和反序列化)
//json
//Google protobuf
//把Request结构发送到服务器上
    sendto(fd, 0,(sockaddr*)&server_addr,sizeof(server_addr));
//尝试读取服务器上的返回信息
    Response resp;
    recvfrom(fd,&resp,sizeof(resp),0,NULL,NULL);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/xuruhua/article/details/80320547