这里我们的自定执行协议和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;
}